<?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=Anastasia</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=Anastasia"/>
	<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/Anastasia"/>
	<updated>2026-10-22T20:43:34Z</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:Avasilenko&amp;diff=17707</id>
		<title>Обсуждение участника:Avasilenko</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:Avasilenko&amp;diff=17707"/>
		<updated>2016-11-16T14:15:11Z</updated>

		<summary type="html">&lt;p&gt;Anastasia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;п. 2.4&lt;br /&gt;
&lt;br /&gt;
* не указано, какая реализация алгоритма использовалась - собственная или библиотечная&lt;br /&gt;
*: [[Участник:Zhum|Zhum]] ([[Обсуждение участника:Zhum|обсуждение]]) 11:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** &#039;&#039;Ссылка на реализацию была указана в конце параграфа. Явно добавили указание, что реализация собственная.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Anastasia</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:Avasilenko/Partitioning_Around_Medoids_(PAM)&amp;diff=17651</id>
		<title>Участник:Avasilenko/Partitioning Around Medoids (PAM)</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:Avasilenko/Partitioning_Around_Medoids_(PAM)&amp;diff=17651"/>
		<updated>2016-11-16T12:29:23Z</updated>

		<summary type="html">&lt;p&gt;Anastasia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Partitioning Around Medoids&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(T*kn^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*(n-1)+2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;k+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(T*kn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(k(n-k))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Авторы&#039;&#039;&#039;:&lt;br /&gt;
* [[Участник:Avasilenko|А.Э.Василенко]] (отвечает за программистскую составляющую);&lt;br /&gt;
* [[Участник:Anastasia|А.В.Тузикова]] (отвечает за математическую составляющую).&lt;br /&gt;
Вклад авторов считать равноценным, чётких границ ответственности провести невозможно.&lt;br /&gt;
&lt;br /&gt;
==Свойства и структура алгоритма==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
 &lt;br /&gt;
Объединение схожих объектов в группы - один из важнейших видов человеческой деятельности&amp;lt;ref&amp;gt;Rousseeuw P. J., Kaufman L. Finding Groups in Data. – Wiley Online Library, 1990.&amp;lt;/ref&amp;gt;. Более того - это важная часть процесса познания мира, в котором мы живем. Мы учим детей различать кошек и собак, воду и песок, мужчин и женщин путем постоянного развития и улучшения подсознательных схем классификации. Примеры есть и во взрослой жизни – в химии необходимо классифицировать соединения, в археологии – объединять находки по периодам и т.д.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задача кластеризации&#039;&#039;&#039; - разделение множества объектов на заданное число множеств с минимизацией некоторого функционала - является популярной задачей, относится к разделу машинного обучения и находит применение в таких областях, как анализ текста, биоинформатика, интеллектуальные транспортные системы и др. &amp;lt;ref&amp;gt; Речкалов Т.В. Параллельный алгоритм кластеризации для многоядерного сопроцессора Intel Xeon Phi // Суперкомпьютерные дни в России: Труды vеждународной конференции. – М.: Изд-во МГУ, 2015, c. 532.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существует несколько видов кластеризации&amp;lt;ref&amp;gt;Маннинг К.Д., Введение в информационный поиск: пер. с англ. / К.Д. Маннинг, П. Рагхаван, Х.Шютце - М. : Вильямс, 2011. - 528.&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;плоская кластеризация&#039;&#039; (&#039;&#039;flat clustering&#039;&#039;) - порождает совокупность кластеров, не имеющих явных взаимосвязей;&lt;br /&gt;
* &#039;&#039;иерархическая кластеризация&#039;&#039; (&#039;&#039;hierarchical clustering&#039;&#039;) - создаёт иерархию кластеров.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PAM&#039;&#039;&#039; (&#039;&#039;&#039;Partitioning Around Medoids&#039;&#039;&#039;) - плоский алгоритм кластеризации, позволяющий выделить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров (множеств), удовлетворяющих следующим свойствам:&lt;br /&gt;
 &lt;br /&gt;
*   каждая группа содержит хотя бы один объект;&lt;br /&gt;
*   каждый объект принадлежит ровно одной группе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Модель &amp;lt;ref&amp;gt;Kaufman, L. and Rousseeuw, P.J., Clustering by means of Medoids. In: Y. Dodge and North-Holland, editor. Statistical Data Analysis Based on the L1-Norm and Related Methods. Springer US; 1987, p. 405–416.&amp;lt;/ref&amp;gt;, лежащая в основе алгоритма PAM, основана на выборе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов, являющихся характерными точками соответствующего кластера. Таким образом, кластерам сопоставляются принадлежащие им объекты, называемые &#039;&#039;&#039;медоидами&#039;&#039;&#039;, на основании которых распределяются остальные объекты по принципу наибольшего сходства. Cама модель называется моделью &#039;&#039;&#039;k-medoids&#039;&#039;&#039; (не путать с моделью &#039;&#039;k-median&#039;&#039;).&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
PAM состоит из двух фаз: &#039;&#039;&#039;BUILD&#039;&#039;&#039; и &#039;&#039;&#039;SWAP&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
*   на фазе BUILD выполняется первичная кластеризация, в ходе которой последовательно выбираются &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов в качестве медоидов;&lt;br /&gt;
*   фаза SWAP представляет собой итерационный процесс, в ходе которого производятся попытки улучшить множество медоидов. Алгоритм выполняет поиск пары объектов (медоид, не-медоид), минимизирующих целевую функцию при замене, после чего обновляет множество медоидов.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации алгоритма выбирается пара (медоид, не-медоид) такая, что замена медоида &amp;lt;math&amp;gt;x_{m_l}&amp;lt;/math&amp;gt; на не-медоид &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; дает лучшую кластеризацию из возможных. Оценка кластеризации выполняется с помощью целевой функции, вычисляемой как сумма расстояний от каждого объекта до ближайшего медоида:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum_{j = 1}^n \min_{1 \leq l \leq k} \rho ( x_{m_l},x_{o_h} )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура изменения множества медоидов повторяется, пока есть возможность улучшения значения целевой функции.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Исходные данные&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
*   множество кластеризуемых объектов &amp;lt;math&amp;gt;X = \{ x_1, x_2, ... , x_n \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; - кортеж, состоящий из &amp;lt;math&amp;gt; w &amp;lt;/math&amp;gt; вещественных чисел;&lt;br /&gt;
*   симметрическая матрица &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, элементы матрицы &amp;lt;math&amp;gt;d_{ij}=d(i,j)&amp;lt;/math&amp;gt; - вычисленные расстояния между объектами &amp;lt;math&amp;gt;x_i, x_j&amp;lt;/math&amp;gt;;&lt;br /&gt;
*   количество кластеров &amp;lt;math&amp;gt;k \leq n.&amp;lt;/math&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Обозначения&#039;&#039;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;M = \{ x_{m_1}, x_{m_2}, ... , x_{m_k} \} &amp;lt;/math&amp;gt; - множество медоидов, &amp;lt;math&amp;gt; M \subseteq X ;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;O = \{ x_{o_1}, x_{o_2}, ... , x_{o_r} \} &amp;lt;/math&amp;gt; - множество не-медоидов, &amp;lt;math&amp;gt; O \subseteq X, &amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;r=n-k;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;d_{ij}=\rho (x_i, x_j )&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \rho  : X \times X \rightarrow R &amp;lt;/math&amp;gt; — метрика расстояния;&lt;br /&gt;
*   &amp;lt;math&amp;gt;F_{M,O} = \sum_{j = 1}^{n} \min_{ x_{m_l} \in M} \rho ( x_{m_l},x_{o_j} )&amp;lt;/math&amp;gt; - значение целевой функции для заданных множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;T^i&amp;lt;/math&amp;gt; - изменение целевой функции на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-м шаге фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Выходные данные&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;M = \{ x_{m_1}, x_{m_2}, ... , x_{m_k} \}&amp;lt;/math&amp;gt; - множество медоидов;&lt;br /&gt;
* &amp;lt;math&amp;gt;K_{m_i} = \{ x_{o_h} \in O \| x_{m_i} = \arg \min_{x_{m_s} \in M} \rho (x_{o_h}, x_{m_s}) \}, 1 \leq i \leq k&amp;lt;/math&amp;gt; - искомые кластеры.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Вычислительные формулы метода&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
*   &#039;&#039;фаза BUILD&#039;&#039; (состоит из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; шагов последовательного выбора &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; медоидов):&lt;br /&gt;
**   &amp;lt;math&amp;gt;O_0 = X, M_0 = \varnothing ;&amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_1} = \arg \min_{x_{o_h} \in O_0} \sum_{j = 1}^n \rho \left ( x_{o_h},x_j \right ), O_1 = O_0 \backslash \{x_{m_1}\}, M_1 = M_1 \cup \{x_{m_1}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_2} = \arg \min_{x_{o_h} \in O_1} \sum_{j = 1}^{n} \min ( \rho ( x_{m_1},x_j ), \rho ( x_{o_h},x_j ) ), O_2 = O_1 \backslash \{x_{m_2}\}, M_2 = M_1 \cup \{x_{m_2}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_3} = \arg \min_{x_{o_h} \in O_2} \sum_{j = 1}^{n} \min_{1 \leq l \leq 2} ( \rho ( x_{m_l},x_j ) , \rho ( x_{o_h},x_j ) ) , O_3 = O_2 \backslash \{x_{m_3}\}, M_3 = M_3 \cup \{x_{m_3}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
** ...&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_k} = \arg \min_{x_{o_h} \in O_{k-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{k-1}} ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j ) ) , O_k = O_{k-1} \backslash \{x_{m_k}\}, M_k = M_{k-1} \cup \{x_{m_k}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;фаза SWAP&#039;&#039; (итерационный процесс):&lt;br /&gt;
** начальное приближение: &amp;lt;math&amp;gt;O_0 = O_k^{BUILD}, M_0 = M_k^{BUILD};&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й шаг итерации:&lt;br /&gt;
*** вычисление целевой функции при оптимальной замене (замене, при которой достигается лучшая кластеризация из возможных на текущей итерации): &amp;lt;br&amp;gt;&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j) ); &amp;lt;/math&amp;gt;&lt;br /&gt;
*** определение пары (медоид, не-медоид), на которой достигается оптимальная замена: &amp;lt;br&amp;gt;&amp;lt;math&amp;gt; (x_{m_s}, x_{o_h}) = \arg F^i; &amp;lt;/math&amp;gt;&lt;br /&gt;
*** проверка критерия останова;&lt;br /&gt;
*** изменение множеств в соответствии с выбранной парой &amp;lt;math&amp;gt; (x_{m_s}, x_{o_h}):&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&amp;lt;math&amp;gt;M_i = M_{i-1} \backslash \{x_{m_s}\} \cup \{x_{o_h}\} , O_i = O_{i-1} \cup \{x_{m_s}\} \backslash \{x_{o_h}\} ;&amp;lt;/math&amp;gt;&lt;br /&gt;
** критерий останова:&lt;br /&gt;
*** &amp;lt;math&amp;gt;T^i = F^{i-1} - F^{i} \leq 0 .&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро алгоритма PAM на этапе BUILD&#039;&#039;&#039; состоит из многочисленных вычислений значений целевой функции при различных вариантах выбора дополнительного медоида (шаг алгоритма &amp;lt;math&amp;gt;1 \leq i \leq k&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1}} ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j ) ) = \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \overline{MIN}_{i, x_{o_h}}^{(j)},&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;\overline{MIN}_{1, x_{o_h} \in O_0} = \{ \rho (x_{o_h}, x_j ) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{o_h} \in O_{i-1}} = \{ \min ( \overline{MIN}_{i-1, x_{m_{i-1}}}^{(j)}, \rho (x_{o_h}, x_j) ) \| 1 \leq j \leq n \}, \forall i: 1 &amp;lt; i \leq k.&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;|O_{i-1}| = n-i+1&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Оптимизация&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* таким образом, на каждой последующей итерации можно использовать величину, вычисленную на предыдущем шаге, что позволяет сократить число вычислений минимумов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро алгоритма PAM на этапе SWAP&#039;&#039;&#039; состоит из многочисленных вычислений значений целевой функции при различных вариантах замены некоторого существующего медоида на элемент из числа не-медоидов. &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-я итерация фазы SWAP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j) ) =&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;= \min_{x_{m_s} \in M_{i-1} } \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Оптимизация&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* таким образом, при поиске пары (медоид, не-медоид), наилучшим образом минимизирующей целевую функцию, происходит поиск минимума по всем возможным элементам &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, для которых вычисляется &amp;lt;math&amp;gt;\sum_{j = 1}^{n} \min (a, b)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt; \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )),&amp;lt;/math&amp;gt; и является инвариантом по отношению к &amp;lt;math&amp;gt;\min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) ),&amp;lt;/math&amp;gt; что позволяет предвычислить элемент &amp;lt;math&amp;gt;a.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Опишем макрооперации алгоритма&#039;&#039;:&lt;br /&gt;
* в случае если алгоритму PAM на вход подаётся набор точек с их координатами в пространстве &amp;lt;math&amp;gt;R^w,&amp;lt;/math&amp;gt; то необходимо вычислить матрицу расстояний. Для этого может быть использована, например, евклидова метрика:&lt;br /&gt;
*: &amp;lt;math&amp;gt;\rho (p,q)=\sqrt{(p_1-q_1)^2+(p_2-q_2)^2+\dots+(p_w-q_w)^2} = \sqrt{\sum_{j=1}^w (p_j-q_j)^2} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p, q \in R^w;&amp;lt;/math&amp;gt;&lt;br /&gt;
* нахождение минимального среди значений, принимаемых некоторой функцией &amp;lt;math&amp;gt;value,&amp;lt;/math&amp;gt; определённой на дискретном множестве &amp;lt;math&amp;gt;Y=\{y_i\}, \, i = \overline{(1,r)}:&amp;lt;/math&amp;gt;&lt;br /&gt;
*: &amp;lt;math&amp;gt;minimum_{y \in Y } (value (y)) = \min \Bigg(value(y_1), \min \bigg(value(y_2), \min \Big(\dots , \min(value(y_{r-1}), value(y_{r})) ... \Big) \bigg)\Bigg);&amp;lt;/math&amp;gt;&lt;br /&gt;
* вычисление вектора инвариантов, используемых при оптимизации фазы SWAP (см. вычислительное ядро алгоритма):&lt;br /&gt;
*: &amp;lt;math&amp;gt;\overline{a} = \{ minimum_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l}, x_j ) ) \| 1 \leq j \leq n \},&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;i - &amp;lt;/math&amp;gt;номер итерации;&lt;br /&gt;
* вычисление вектора расстояний от каждой точки заданного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; до ближайшего медоида из множества &amp;lt;math&amp;gt;M_{i-1} \backslash \{x_{m_s}\},&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;i - &amp;lt;/math&amp;gt;номер итерации фазы SWAP: &lt;br /&gt;
*: &amp;lt;math&amp;gt;\overline{b} = \{ \min (\overline{a}^{(j)}, \rho ( x_{o_p}, x_j )) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
* сложение компонент вектора: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline{f}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Макроструктура вычислительного ядра алгоритма PAM&#039;&#039; может быть выражена через макрооперации следующим образом:&lt;br /&gt;
* для ядра фазы BUILD:&lt;br /&gt;
*::: &amp;lt;math&amp;gt;F^i = minimum_{ x_{o_h} \in O_{i-1} } ( S \, ( \overline{f} (x_{o_h}) )),&amp;lt;/math&amp;gt;&lt;br /&gt;
*::: &amp;lt;math&amp;gt;\overline{f} = \{ \min \,( \overline{MIN}_{i, x_{o_h}}^{(j)}, \rho (x_{o_h}, x_j)) \| 1 \leq j \leq n \}, &amp;lt;/math&amp;gt; где&lt;br /&gt;
*# &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;n-i+1&amp;lt;/math&amp;gt; раз;&lt;br /&gt;
*# &amp;lt;math&amp;gt;minimum&amp;lt;/math&amp;gt; находится &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; раз при вычислении наилучшего значения целевой функции на текущей итерации.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* для ядра фазы SWAP:&lt;br /&gt;
*::: &amp;lt;math&amp;gt;F^i = minimum_{ x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1} } ( S \, ( \overline{b} \, ( x_{o_h}, \overline{a} \, (x_{m_s}) ) )),&amp;lt;/math&amp;gt; где:&lt;br /&gt;
*# &amp;lt;math&amp;gt;minimum&amp;lt;/math&amp;gt; находится &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; раз  в процессе вычисления макрооперации &amp;lt;math&amp;gt;\overline {a};&amp;lt;/math&amp;gt;&lt;br /&gt;
*# &amp;lt;math&amp;gt;\overline {a}&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; раз и использует вычисленные на шаге 1 минимальные значения;&lt;br /&gt;
*# &amp;lt;math&amp;gt;\overline {b}&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;k(n-k)&amp;lt;/math&amp;gt; раз и использует вычисленные на шаге 2 значения &amp;lt;math&amp;gt;\overline {a};&amp;lt;/math&amp;gt;&lt;br /&gt;
*# &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;k(n-k)&amp;lt;/math&amp;gt; раз и использует вычисленные на шаге 3 значения &amp;lt;math&amp;gt;\overline {b};&amp;lt;/math&amp;gt;&lt;br /&gt;
*# &amp;lt;math&amp;gt;minimum&amp;lt;/math&amp;gt; находится &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; раз при вычислении наилучшего значения целевой функции на текущей итерации.&lt;br /&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;&#039;&#039;  : Множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; или матрица расстояний &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, количество кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;&lt;br /&gt;
 &#039;&#039;&#039;Выход&#039;&#039;&#039; : Множество медоидов &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
 0  Если на вход было подано множество объектов, необходимо предварительно вычислить матрицу расстояний;&lt;br /&gt;
 1  Инициализация множеств &amp;lt;math&amp;gt;M := \varnothing, O := X;&amp;lt;/math&amp;gt;&lt;br /&gt;
 &amp;amp;nbsp;&lt;br /&gt;
    // фаза BUILD&lt;br /&gt;
 2  &#039;&#039;&#039;for (int i := 1; i &amp;lt;= k; i++)&#039;&#039;&#039; {&lt;br /&gt;
        // Найти &amp;lt;math&amp;gt;x_{m_i}:&amp;lt;/math&amp;gt;&lt;br /&gt;
        {&lt;br /&gt;
 3          Для всех &amp;lt;math&amp;gt;x_{o_h} \in O&amp;lt;/math&amp;gt; вычислить &amp;lt;math&amp;gt;F_{M \cup \{x_{o_h}\}, O \backslash \{x_{o_h}\}};&amp;lt;/math&amp;gt;&lt;br /&gt;
 4          Положить &amp;lt;math&amp;gt;x_{m_i}&amp;lt;/math&amp;gt; равным &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, соответствующему минимальному из вычисленных &amp;lt;math&amp;gt;F;&amp;lt;/math&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
 5      Обновить множества &amp;lt;math&amp;gt;M := M \cup \{x_{m_i}\}, O := O \backslash \{x_{m_i}\};&amp;lt;/math&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
    // фаза SWAP&lt;br /&gt;
 6  &#039;&#039;&#039;while (1)&#039;&#039;&#039; {&lt;br /&gt;
        // Найти пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h}),&amp;lt;/math&amp;gt; на которой достигается оптимальная замена:&lt;br /&gt;
        {&lt;br /&gt;
 7          Для всех &amp;lt;math&amp;gt;x_{m_i} \in M, x_{o_j} \in O&amp;lt;/math&amp;gt; вычислить &amp;lt;math&amp;gt;F^i;&amp;lt;/math&amp;gt; // вычисление проводить с учётом приведённой ранее оптимизации (см. 1.3 [[#Вычислительное ядро алгоритма|Вычислительное ядро алгоритма]]);&lt;br /&gt;
 8          Положить пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; равной паре &amp;lt;math&amp;gt;(x_{m_i}, x_{o_j})&amp;lt;/math&amp;gt;, соответствующей минимальному из вычисленных &amp;lt;math&amp;gt;F;&amp;lt;/math&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
 9      Вычислить &amp;lt;math&amp;gt;T^i;&amp;lt;/math&amp;gt; // критерий останова (см. 1.2 [[#Математическое описание алгоритма|Математическое описание алгоритма]])&lt;br /&gt;
 10     &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;(T^i &amp;gt; 0)&amp;lt;/math&amp;gt; {&lt;br /&gt;
 11         Обновить множества &amp;lt;math&amp;gt;M := M \backslash \{x_{m_s}\} \cup \{x_{o_h}\}, O := O \cup \{x_{m_s}\} \backslash \{x_{o_h}\};&amp;lt;/math&amp;gt;&lt;br /&gt;
 12     } &#039;&#039;&#039;else&#039;&#039;&#039; {&lt;br /&gt;
 13         &#039;&#039;&#039;break&#039;&#039;&#039;;&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;&#039;&#039;. Необходимо предварительно вычислить матрицу расстояний и сохранить её в памяти, так как в ходе вычисления алгоритма многократно используются расстояния между элементами, а вычисление каждого из них является ресурсоёмкой операцией из нескольких умножений и одного извлечения квадратного корня.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Минимизация кеш-промахов&#039;&#039;&#039;. Матрица расстояний, к которой постоянно выполняется доступ на чтение для вычисления минимумов и их суммирования, должна храниться в памяти как матрица размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, несмотря на то, что она симметрическая и достаточно хранить лишь половину (элементы над или под главной диагональю). Данная оптимизация потребует использования в 2 раза большего количества памяти для хранения расстояний (а это является главным расходом памяти программы, так как все остальные используемые данные являются временными (локальными для каждой операции) и представляют из себя несколько векторов длинной &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов). Однако так как в данном алгоритме доступ к матрице осуществляется построчно (в  [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]] поэлементно ищутся  минимумы 2-х векторов, после чего все они складываются), то в этом случае из матрицы можно будет читать данные по строкам подряд, что снижает количество кеш-промахов. Использование только половины матрицы приводит к частым промахам в кеше в связи с необходимостью загрузки части векторов по строкам, а части - по столбцам.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления &#039;&#039;&#039;матрицы расстояний&#039;&#039;&#039; требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций вычисления расстояний;&lt;br /&gt;
* сложность каждой операции вычисления расстояния (для случая использования Евклидовой метрики) равна &amp;lt;math&amp;gt;2*w-1&amp;lt;/math&amp;gt; операций сложения и вычитания, &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; операций возведения в квадрат (умножения) и &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операции извлечения квадратного корня.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основании формулы из описания &#039;&#039;&#039;вычислительного ядра фазы BUILD&#039;&#039;&#039; определим сложность выполнения всего этапа.&lt;br /&gt;
&lt;br /&gt;
Обозначим:&lt;br /&gt;
*&amp;lt;math&amp;gt;summs&amp;lt;/math&amp;gt; - операция сложения двух вещественных чисел;&lt;br /&gt;
*&amp;lt;math&amp;gt;mins&amp;lt;/math&amp;gt; - операция нахождения минимума для двух вещественных чисел.&lt;br /&gt;
&lt;br /&gt;
Тогда, количество операций равно:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = ( ( (n-1) summs ) * (n-1+1) + (n-1+1-1)mins) + \sum_{i = 2}^{k} ( ( (1 mins)*(n-1) + (n-1) summs ) * (n-i+1) + (n-i+1-1)mins) \Rightarrow&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Rightarrow S =&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = ( ( 0 ) * (n-1+1) + (n-1+1-1)mins) + \sum_{i = 2}^{k} ( ( (1 mins)*(n-1)) * (n-i+1) + (n-i+1-1)mins ) &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = \sum_{i = 1}^{k} ( ( (n-1) summs ) * (n-i+1) ) &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
=&lt;br /&gt;
&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
=&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = n^2(k-1) - \frac{1}{2}(nk^2 - nk) + n - k &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = n^2k - \frac{1}{2}(nk^2 + nk - k^2 + k ) &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность фазы BUILD есть &amp;lt;math&amp;gt;O(kn^2)&amp;lt;/math&amp;gt; как по количеству найденных минимумов, так и по количеству операций сложения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основании формулы из описания &#039;&#039;&#039;вычислительного ядра фазы SWAP&#039;&#039;&#039; определим сложность вычисления целевой функции &amp;lt;math&amp;gt;F^i&amp;lt;/math&amp;gt; с использованием оптимизации процесса нахождения минимума (см. раздел [[#Вычислительное ядро алгоритма|Вычислительное ядро алгоритма]]). Количество операций равно:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = ( ( (1 mins)*(n-1) + (n-1) summs )*(n-k) + n*((k-1-1) mins) )*k \Rightarrow&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Rightarrow S =&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = ( ((1 mins)*(n-1) )*(n-k) + n*((k-1-1) mins) )*k = kn^2 - 3nk + k^2 &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = ( ( (n-1) summs )*(n-k) )*k = (n-1)(n-k)k &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность одной итерации фазы SWAP есть &amp;lt;math&amp;gt;O(kn^2)&amp;lt;/math&amp;gt; как по количеству найденных минимумов, так и по количеству операция сложения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Полученные оценки позволяют говорить о том, что PAM относится к алгоритмам &#039;&#039;&#039;с квадратичной сложностью&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Основная вычислительная сложность алгоритма PAM приходится на фазу SWAP, т.к. сложность одной её итерации сопоставима со сложностью всей фазы BUILD, однако SWAP может содержать в себе огромное число итераций.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
==== Информационный граф фазы BUILD ====&lt;br /&gt;
 &lt;br /&gt;
Опишем граф фазы BUILD как аналитически, так и в виде рисунка.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Граф состоит из шести групп вершин&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
# Операция M, соответствующая &#039;&#039;&#039;первой&#039;&#039;&#039; группе вершин, осуществляет изменение множества медоидов:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M_{It} = M_{It-1} \cup \overline{x}_{m_{It}}, &amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;\overline{x}_{m_{It}} = \overline{x}_{o_{It}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; (номер итерации), соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_{It}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M_{It-1}&amp;lt;/math&amp;gt; - множество медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It \leq k &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция O, соответствующая &#039;&#039;&#039;второй&#039;&#039;&#039; группе вершин, осуществляет изменение множества не-медоидов:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;O_{It} = O_{It-1} \backslash \overline{x}_{o_{It}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt;, соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_{It}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;O_{It-1}&amp;lt;/math&amp;gt; - множество не-медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It \leq k &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;третьей&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{c}=\overline{c}_{x_{o_p} } =  \begin{cases} \{ \rho (x_{o_p}, x_j ) \| 1 \leq j \leq n \}, It=1 &amp;amp; \quad\\ \{ \min ( \overline{MIN}^{(j)}, \rho (x_{o_p}, x_j) ) \| 1 \leq j \leq n \}, 1&amp;lt;It \leq k &amp;amp; \quad\\  \end{cases} .&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-It+1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = 1:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** &amp;lt;math&amp;gt;\overline{x}_{o_p}&amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;1 &amp;lt; It \leq k:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:**&amp;lt;math&amp;gt;\overline{x}_{o_p}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#:**&amp;lt;math&amp;gt;\overline{MIN}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из шестой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция S, соответствующая &#039;&#039;&#039;четвертой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline {c}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-It+1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{c}_{ x_{o_p} }&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из третьей группы с координатами &amp;lt;math&amp;gt; It, p.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M1, соответствующая &#039;&#039;&#039;пятой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M1 = (F^{It}; x_{o_{It}}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt; \begin{cases}&lt;br /&gt;
F^{It} = \min_{x_{o_p} \in O_{It-1}} S &amp;amp; \quad\\&lt;br /&gt;
x_{o_{It}} = \arg F^{It} &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из четвертой группы с первой координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;n-It+1&amp;lt;/math&amp;gt; величина.&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция MIN, соответствующая &#039;&#039;&#039;шестой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{MIN}=\overline{MIN}_{It,x_{m_{It}} } =  \begin{cases}&lt;br /&gt;
\{ \rho (x_{m_{It}            }, x_j ) \| 1 \leq j \leq n \}, It=1 &amp;amp; \quad\\&lt;br /&gt;
\{ \min ( \overline{MIN}^{(j)}, \rho (x_{m_{It}}, x_j) ) \| 1 \leq j \leq n \}, 1&amp;lt;It \leq k &amp;amp; \quad\\&lt;br /&gt;
 \end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k-1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{MIN}_{It-1,x_{m_{It-1}}} &amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из шестой группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;x_{m_{It}} =  x_{o_{It}} &amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описанный граф в общем случае представлен на Рис.1, отображен шаг с номером &amp;lt;math&amp;gt;It, 1&amp;lt;It&amp;lt;k&amp;lt;/math&amp;gt; фазы BUILD.&lt;br /&gt;
Обозначения:&lt;br /&gt;
# вершины первой группы обозначены фиолетовым цветом и подписаны как &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины  второй группы обозначены синим цветом и подписаны как &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины третьей группы обозначены жёлтым цветом и подписаны как &amp;lt;math&amp;gt;\overline{c}_{x_{o_p} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины четвертой группы обозначены серым цветом и подписаны как &amp;lt;math&amp;gt;S;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины пятой группы обозначены зеленым цветом и подписаны как &amp;lt;math&amp;gt;M1;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины шестой группы обозначены красным цветом и подписаны как &amp;lt;math&amp;gt;MIN;&amp;lt;/math&amp;gt;&lt;br /&gt;
# синим дугам сопоставлены метки, отражающие данные, используемые в соответствующих жёлтых вершинах.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Pam build 1.png|thumb|center|800px|Рисунок 1. Граф фазы BUILD алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На Рис.2 представлен граф фазы BUILD для случая &amp;lt;math&amp;gt;n=6, k=3.&amp;lt;/math&amp;gt; Вершины, соответствующие операциям, получающим входные данные и производящим выходные данные, увеличены и выделены толстыми границами.&lt;br /&gt;
&lt;br /&gt;
[[file:Pam build 2.png|thumb|center|1100px|Рисунок 2. Граф фазы BUILD алгоритма для n = 6, k = 3. ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Информационный граф фазы SWAP ====&lt;br /&gt;
 &lt;br /&gt;
Опишем граф фазы SWAP как аналитически, так и в виде рисунка.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Граф состоит из семи групп вершин&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
# Операция M, соответствующая &#039;&#039;&#039;первой&#039;&#039;&#039; группе вершин, осуществляет изменение множества медоидов.&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; (номер итерации), соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; T),&amp;lt;/math&amp;gt; принимая все целочисленные значения, где:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;T\in \N&amp;lt;/math&amp;gt; - количество выполнений фазы SWAP во время работы алгоритма PAM.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* результат срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M_{It-1}&amp;lt;/math&amp;gt; - множество медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It &amp;lt; T &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; T -1 &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = T - 1&amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы SWAP.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция O, соответствующая &#039;&#039;&#039;второй&#039;&#039;&#039; группе вершин, осуществляет изменение множества не-медоидов.&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt;, соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; T),&amp;lt;/math&amp;gt; принимая все целочисленные значения, где:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;T\in \N&amp;lt;/math&amp;gt; - количество выполнений фазы SWAP во время работы алгоритма PAM.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* результат срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;O_{It-1}&amp;lt;/math&amp;gt; - множество не-медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It &amp;lt; T &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;третьей&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{a}=\overline{a}_{x_{m_i} } = \{ \min_{ x_{m_l} \in M  \backslash \{x_{m_i}\} }  \rho ( x_{m_l},x_j ) \| 1 \leq j \leq n \}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументом операции является &amp;lt;math&amp;gt;\overline{x}_{m_i}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;четвертой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{b}=\overline{b}_{x_{m_i} x_{o_p} } =  \{ \min (\overline{a}_{ x_{m_i}}^{(j)}, \rho ( x_{o_p},x_j )) \| 1 \leq j \leq n \}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_p}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{a}_{x_{m_i}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из третьей группы с координатами &amp;lt;math&amp;gt;It, i.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция S, соответствующая &#039;&#039;&#039;пятой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline {b}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{b}_{x_{m_i} x_{o_p} }&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из четвертой группы с координатами &amp;lt;math&amp;gt;It, i, p.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M1, соответствующая &#039;&#039;&#039;шестой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M1 = (F_{x_{o_p}}^{It}; x_{o_p}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt; \begin{cases}&lt;br /&gt;
F_{x_{o_p}}^{It} = \min_{x_{o_p} \in O} S &amp;amp; \quad\\&lt;br /&gt;
x_{o_p} = \arg F_{x_{o_p}}^{It} &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из пятой группы с первыми двумя координатами &amp;lt;math&amp;gt;It, i,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;n-k&amp;lt;/math&amp;gt; величин.&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M2, соответствующая &#039;&#039;&#039;седьмой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M2 = (F_{x_{o_p}, x_{m_i}}^{It}; x_{m_i}; x_{o_p}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;\begin{cases}&lt;br /&gt;
F_{x_{o_p}, x_{m_i}}^{It} = \min (\min_{x_{m_i} \in M} (F_{x_{o_p}}^{It}), M2_{It-1}) &amp;amp; \quad\\&lt;br /&gt;
x_{m_i} = \arg \min_{x_{m_i} \in M} M1 &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M1 = (F_{x_{o_p}}^{It}; x_{o_p})&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из шестой группы с координатами &amp;lt;math&amp;gt;It, i,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; величин;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M2_{It-1}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результаты срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; T&amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = T&amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описанный граф в общем случае представлен на Рис.3, отображена одна итерация фазы SWAP.&lt;br /&gt;
Обозначения:&lt;br /&gt;
# вершины первой группы обозначены фиолетовым цветом и подписаны как &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины второй группы обозначены синим цветом и подписаны как &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины третьей группы обозначены желтым цветом и подписаны как &amp;lt;math&amp;gt;\overline{a}_{x_{m_i} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины четвертой группы обозначены оранжевым цветом и подписаны как &amp;lt;math&amp;gt;\overline{b}_{x_{m_i o_p} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины пятой группы обозначены серым цветом и подписаны как &amp;lt;math&amp;gt;S;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины шестой группы обозначены зеленым цветом и подписаны как &amp;lt;math&amp;gt;M1;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины седьмой группы обозначены красным цветом и подписаны как &amp;lt;math&amp;gt;M2;&amp;lt;/math&amp;gt;&lt;br /&gt;
# синим дугам сопоставлены метки, отражающие данные, используемые в соответствующих оранжевых вершинах;&lt;br /&gt;
# фиолетовым дугам сопоставлены метки, отражающие данные, используемые в соответствующих жёлтых вершинах.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Pam swap 1.png|thumb|center|1100px|Рисунок 3. Граф фазы SWAP алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На Рис.4 представлен граф фазы SWAP для случая &amp;lt;math&amp;gt;n=6, k=2, T=3.&amp;lt;/math&amp;gt; Вершины, соответствующие операциям, получающим входные данные и производящим выходные данные, увеличены и выделены толстыми границами.&lt;br /&gt;
&lt;br /&gt;
[[file:Pam swap 2.png|thumb|center|1100px|Рисунок 4. Граф фазы SWAP алгоритма для n = 6, k = 2, T = 3.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
При параллельной реализации алгоритма PAM будем рассматривать параллельные варианты фазы BUILD и SWAP ([[#Возможная параллельная реализация алгоритма PAM|возможная параллельная реализация]]). Покажем, что сложность фазы BUILD сопоставима со сложностью одной итерации фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
Оценки последовательной сложности фаз BUILD и SWAP приведены в параграфе &amp;quot;[[#Последовательная сложность алгоритма|Последовательная сложность алгоритма]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Ресурс параллелизма фазы BUILD ====&lt;br /&gt;
&lt;br /&gt;
Для решения задачи кластеризации методом PAM в параллельном варианте фазы BUILD в предположении доступности неограниченного числа процессов для одной итерации необходимо выполнить:&lt;br /&gt;
*  1 ярус с нахождением &amp;lt;math&amp;gt;\overline{c}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* 1 ярус с нахождением суммы &amp;lt;math&amp;gt;S:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операцию сложения;&lt;br /&gt;
* 1 ярус с нахождением значений элемента &amp;lt;math&amp;gt;M1:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &amp;lt;math&amp;gt;\overline{MIN}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It&amp;gt;1;&amp;lt;/math&amp;gt;&lt;br /&gt;
* 1 ярус с изменением множеств медоидов и не-медоидов (не выполняются операции рассматриваемых типов).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность одного шага фазы BUILD равна: &lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операция сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It=1;&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It&amp;gt;1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность фазы BUILD при числе кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; равна: &lt;br /&gt;
* &amp;lt;math&amp;gt;kn-k&amp;lt;/math&amp;gt; операция сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;3kn - 2n - \frac{1}{2}k^2 - \frac{1}{2}k&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, по сравнению с последовательным, при &amp;lt;math&amp;gt;k, n \to \infty&amp;lt;/math&amp;gt; количество операций на один порядок меньше по параметру &amp;lt;math&amp;gt;n:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt; против &amp;lt;math&amp;gt;O(kn^2).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соотношение количества сложений и взятий минимума для фазы BUILD является постоянным и стремится к &amp;lt;math&amp;gt;3,&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;k, n \to \infty.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Максимальная ширина яруса достигается при вычислении &amp;lt;math&amp;gt;\overline {c}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; и равна &amp;lt;math&amp;gt;n-It+1&amp;lt;/math&amp;gt; для шага &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; фазы BUILD. Максимальная ширина яруса при рассмотрении всей фазы есть &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и достигается на первом шаге.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Ресурс параллелизма фазы SWAP ====&lt;br /&gt;
&lt;br /&gt;
Для решения задачи кластеризации методом PAM в параллельном варианте фазы SWAP в предположении доступности неограниченного числа процессов для одной итерации необходимо выполнить:&lt;br /&gt;
* 1 ярус с нахождением &amp;lt;math&amp;gt;\overline {a}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n(k-1)&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением &amp;lt;math&amp;gt;\overline {b}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением суммы &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;:&lt;br /&gt;
** &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операцию сложения;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &#039;первого&#039; вида &amp;lt;math&amp;gt;(M1 = \min_{x_{o_p} \in O} S):&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-k-1&amp;lt;/math&amp;gt; операцию нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &#039;второго&#039; вида &amp;lt;math&amp;gt;(M2 = \min_{x_{m_i} \in M} M1):&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt; операцию нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с изменением множеств медоидов и не-медоидов (не выполняются операции рассматриваемых типов).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность одной итерации фазы SWAP равна:&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - по количеству операций сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;kn + n - 2&amp;lt;/math&amp;gt; - по количеству операций нахождений минимума для двух чисел.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, по сравнению с последовательным, при &amp;lt;math&amp;gt;k, n \to \infty&amp;lt;/math&amp;gt; количество операций на один порядок меньше по параметру &amp;lt;math&amp;gt;n:&amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt; против &amp;lt;math&amp;gt;O(kn^2).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соотношение количества сложений и взятий минимума для одной итерации фазы SWAP является постоянным и равным &amp;lt;math&amp;gt;k,&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;n \to \infty&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Максимальная ширина яруса достигается при вычислении &amp;lt;math&amp;gt;\overline {b}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; и равна &amp;lt;math&amp;gt;k(n-k).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При использовании выбранной модели, в предположении доступности неограниченного числа вычислителей, фаза BUILD при &amp;lt;math&amp;gt;n \to \infty&amp;lt;/math&amp;gt; требует большего количества операций суммирования на порядок &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, по сравнению с одной итерацией фазы SWAP. В свою очередь, количество операций подсчёта минимума ассимптотически эквивалентны.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные&#039;&#039;:&lt;br /&gt;
* число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество точек упорядоченного множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
* число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество требуемых кластеров;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов, состоящих из &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; вещественных чисел, - попарных расстояний между элементами из множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; за исключением расстояний вида &amp;lt;math&amp;gt;\rho (x, x)=0, x \in X;&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;Объём входных данных&#039;&#039;: &amp;lt;math&amp;gt;n(n-1)&amp;lt;/math&amp;gt; вещественное число и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; целых числа.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Структура хранения данных&#039;&#039;:&lt;br /&gt;
* сразу после считывания входных данных составляется квадратная симметрическая матрица &amp;lt;math&amp;gt;D^{n * n}&amp;lt;/math&amp;gt;, у которой каждый элемент &amp;lt;math&amp;gt;d_{ij}&amp;lt;/math&amp;gt; является вещественным числом - расстоянием &amp;lt;math&amp;gt;\rho (x_i, x_j);&amp;lt;/math&amp;gt;&lt;br /&gt;
* для множества медоидов &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; создаётся массив из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; целых чисел - индексов принадлежащих ему элементов из множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, аналогичный массив &amp;lt;math&amp;gt;n-k&amp;lt;/math&amp;gt; целых чисел создаётся для множества не-медоидов &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
* для пересылки данных, как правило, используется тройка &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}; x_{m_s}; x_{o_h})&amp;lt;/math&amp;gt; или пара &amp;lt;math&amp;gt;(F_{x_{o_h}}^{i_j}; x_{o_h}),&amp;lt;/math&amp;gt; где:&lt;br /&gt;
** &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; - целое число, обозначающее порядковый номер элемента множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; - целое число, обозначающее порядковый номер элемента множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;F_{x_{m_s}, x_{o_h}}^{i_j}&amp;lt;/math&amp;gt; - вещественное число, равное минимальному значению целевой функции, вычисленному в текущем контексте.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Выходные данные&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; целых чисел, составляющих множество &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; вещественное число, являющееся значением целевой функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Объём выходных данных&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;  целых чисел и &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;  вещественное.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности алгоритма является &#039;&#039;линейным&#039;&#039; и равным &amp;lt;math&amp;gt;n.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Вычислительная мощность&#039;&#039; последовательного алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, равна &amp;lt;math&amp;gt;O(T*k).&amp;lt;/math&amp;gt;&lt;br /&gt;
Вычислительная мощность параллельного алгоритма равна &amp;lt;math&amp;gt;O(T*\frac{k}{n}).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм PAM является &#039;&#039;менее чувствительным&#039;&#039; к выбросам данных, чем алгоритм k-средних. Это связано с использованием медоидов, менее подверженных влиянию таких данных.&amp;lt;ref&amp;gt; Егоров А. В., Куприянова Н. И. Особенности методов кластеризации данных // Известия Южного федерального университета. Технические науки. –2011. T. 124, № 11. –С. 174-177.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Фиксированный способ выбора начальных приближений позволяет говорить о воспроизводимости полученных результатов для последовательной реализации. Для параллельной работы алгоритма подобная воспроизводимость отсутствует, так как из-за &#039;&#039;недетерминированности&#039;&#039; выбора элементов, на которых достигается минимальное значение целевой функции для каждой итерации, итоговое множество медоидов и, следовательно, значение целевой функции может меняться.&lt;br /&gt;
&lt;br /&gt;
Алгоритм PAM &#039;&#039;конечен&#039;&#039;, так как:&lt;br /&gt;
* количество операций фазы BUILD конечно;&lt;br /&gt;
* значение целевой фукнции неотрицательно и на каждой итерации фазы SWAP строго уменьшается.&lt;br /&gt;
&lt;br /&gt;
Одно из преимуществ алгоритма PAM заключается в том, что он может работать с любой матрицей различий. В данном случае принципиальное отличие от матрицы расстояний заключается в том, что для матрицы различий может не выполняться неравенство треугольника, так как в основе её построения не обязательно используется метрика.&lt;br /&gt;
&lt;br /&gt;
Основные операция алгоритма PAM: сложение и нахождение минимума. Операция взятия минимума не подвержена процессу накопления ошибки. На каждой итерации алгоритма сложение производится над значениями, взятыми непосредственно из исходных данных. Таким образом, алгоритм PAM не накапливает ошибок в процессе своей работы и является &#039;&#039;устойчивым&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;math&amp;gt;k(n-k) \, \bmod \, p \neq 0&amp;lt;/math&amp;gt; отсутствует возможность равномерно распределить задачи рассчёта &amp;lt;math&amp;gt;\overline{b}&amp;lt;/math&amp;gt; между процессами. Кроме того, если &amp;lt;math&amp;gt;k \, \bmod \, p \neq 0&amp;lt;/math&amp;gt;, то после их распределения для некоторых процессов окажется необходимым вычислить несколько соседних значений &amp;lt;math&amp;gt;\overline{a}.&amp;lt;/math&amp;gt; Таким образом, &#039;&#039;равномерная&#039;&#039; загрузка процессов &#039;&#039;не всегда возможна&#039;&#039;. Помимо этого, агрегирование данных с целью вычисления глобального минимума приводит к простою незадействованных процессов.&lt;br /&gt;
&lt;br /&gt;
Как и большинство алгоритмов кластеризации, PAM может сходиться к некоторому &#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;
==== Возможная параллельная реализация алгоритма PAM ====&lt;br /&gt;
&lt;br /&gt;
Необходимость уменьшения времени решения задачи приводит к потребности в создании паралельной реализации алгоритма. В дальнейшем будем придерживаться следующих допущений:&lt;br /&gt;
* возможно использование &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов;&lt;br /&gt;
* не нарушая общности суждений, множества &amp;lt;math&amp;gt;M, O&amp;lt;/math&amp;gt; - упорядоченны.&lt;br /&gt;
&lt;br /&gt;
Приведённые далее возможные схемы для параллельных реализаций фазы BUILD и фазы SWAP основаны на максимально равномерном распределении задач между процессами.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Возможная параллельная реализация фазы BUILD =====&lt;br /&gt;
&lt;br /&gt;
Главная задача заключается в распараллеливании многочисленных вычислений целевой функции на каждой итерации фазы BUILD:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{o_h} \in O_{i-1}} F_{x_{o_h}}^i,&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;F_{x_{o_h}}^i = \sum_{j = 1}^{n} \overline{MIN}_{i, x_{o_h}}^{(j)},&amp;lt;/math&amp;gt; где&lt;br /&gt;
: &amp;lt;math&amp;gt;\overline{MIN}_{1, x_{o_h} \in O_0} = \{ \rho (x_{o_h}, x_j ) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{o_h} \in O_{i-1}} = \{ \min ( \overline{MIN}_{i-1, x_{m_{i-1}}}^{(j)}, \rho (x_{o_h}, x_j) ) \| 1 \leq j \leq n \}, \forall i: 1 &amp;lt; i \leq k.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Схема реализации&#039;&#039;: &amp;lt;br&amp;gt;(далее &amp;lt;math&amp;gt;0 &amp;lt; i \leq k &amp;lt;/math&amp;gt; - номер текущей итерации)&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## положим:&lt;br /&gt;
##: &amp;lt;math&amp;gt;pos = p-(n-i+1) \, \bmod \, p;&amp;lt;/math&amp;gt;&lt;br /&gt;
## на каждой итерации процессу необходимо вычислить &amp;lt;math&amp;gt;r_j&amp;lt;/math&amp;gt; значений целевой функции для соответствующих ему элементов &amp;lt;math&amp;gt;x_{o_h}, ..., x_{o_{h+(r_j-1)}}:&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt; r_j = \begin{cases}&lt;br /&gt;
    \lfloor \frac{n-i+1}{p} \rfloor , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    \lceil \frac{n-i+1}{p} \rceil , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;h = \begin{cases}&lt;br /&gt;
    r_j*j , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    (r_j-1)*pos + (j-pos)*r_j , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# каждому процессу с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## найти минимум среди значений целевой функции &amp;lt;math&amp;gt;F_{x_{o_h}}^i&amp;lt;/math&amp;gt; для каждого из значений параметра &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt; &lt;br /&gt;
##* в данном случае может быть использована оптимизация, описанная в [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]];&lt;br /&gt;
## для процессов с номером &amp;lt;math&amp;gt;j \neq 0&amp;lt;/math&amp;gt; переслать процессу с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt; пару &amp;lt;math&amp;gt;(x_{o_h}, F_{x_{o_h}}^i)&amp;lt;/math&amp;gt; для всех обработанных &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# для процесса с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;:&lt;br /&gt;
## принять пары от процессов &amp;lt;math&amp;gt;(0, p-1],&amp;lt;/math&amp;gt; в ответ на шаг 2.2;&lt;br /&gt;
## найти &amp;lt;math&amp;gt;x_{o_h},&amp;lt;/math&amp;gt; для которого целевая функция принимает минимальное значение, и положить &amp;lt;math&amp;gt;x_{m_i}:=x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
## вычислить &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{m_i}}&amp;lt;/math&amp;gt;;&lt;br /&gt;
## разослать пару &amp;lt;math&amp;gt;(x_{m_i}, \overline{MIN}_{i, x_{m_i}})&amp;lt;/math&amp;gt; при помощи широковещательной рассылки;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять пару &amp;lt;math&amp;gt;(x_{m_i}, \overline{MIN}_{i, x_{m_i}})&amp;lt;/math&amp;gt; в ответ на шаг 3.4;&lt;br /&gt;
## скорректировать локальные копии множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt;, изменив принадлежность вектора &amp;lt;math&amp;gt;x_{m_i}&amp;lt;/math&amp;gt;, а также обновить хранимое значение вектора &amp;lt;math&amp;gt;\overline{MIN}&amp;lt;/math&amp;gt; для подготовки к следующей итерации;&lt;br /&gt;
## перейти к шагу 2.1.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
После завершения &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; шагов фазы BUILD, множества &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt; (одинаковые для каждого процесса согласно приведенной схеме), а так же значение целевой функции являются выходными данными фазы BUILD.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Возможная параллельная реализация фазы SWAP =====&lt;br /&gt;
&lt;br /&gt;
Главная задача заключается в распараллеливании многократного вычисления целевой функции на каждой итерации фазы SWAP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} } \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Схема реализации&#039;&#039;: &amp;lt;br&amp;gt;(далее &amp;lt;math&amp;gt;i \in \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;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## положим:&lt;br /&gt;
##: &amp;lt;math&amp;gt;pos = p-(k*(n-k)) \, \bmod \, p;&amp;lt;/math&amp;gt;&lt;br /&gt;
## на каждой итерации процессу необходимо вычислить &amp;lt;math&amp;gt;r_j&amp;lt;/math&amp;gt; значений целевой функции для соответствующих ему пар вида (медоид, не-медоид)   &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h}), (x_{m_s}, x_{o_{h+1}}), ..., (x_{m_s}, x_{o_{n-k}}), (x_{m_{s+1}}, x_{o_0}), (x_{m_{s+1}}, x_{o_1}), . . . \, : &amp;lt;/math&amp;gt;&lt;br /&gt;
##:&amp;lt;math&amp;gt; r_j =   \begin{cases}&lt;br /&gt;
    \lfloor \frac{k*(n-k)}{p} \rfloor , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    \lceil \frac{k*(n-k)}{p} \rceil , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;s = \begin{cases}&lt;br /&gt;
    (r_j*j) \mbox{ div } (n-k) , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
     ((r_j-1)*pos + r_j*(j-pos)) \mbox{ div } (n-k), pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{m_s};&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;h = \begin{cases}&lt;br /&gt;
    (r_j*j) \, \bmod \,  (n-k) , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
     ((r_j-1)*pos + r_j*(j-pos)) \, \bmod \,  (n-k), pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# каждому процессу с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## найти минимум среди вычисленных значений целевой функции для каждого из значений первого параметра &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; по соответствующим ему &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
##* в данном случае может быть использована оптимизация, описанная в [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]];&lt;br /&gt;
## переслать процессу с номером &amp;lt;math&amp;gt;N = s \, \bmod \, p&amp;lt;/math&amp;gt; (если &amp;lt;math&amp;gt;N \neq j&amp;lt;/math&amp;gt;) тройку &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}, x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; для всех обработанных &amp;lt;math&amp;gt;x_{m_s};&amp;lt;/math&amp;gt;&lt;br /&gt;
# для процессов с номерами &amp;lt;math&amp;gt;j&amp;lt;\min (p, k):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять описанные выше тройки от процессов, обработавших элементы &amp;lt;math&amp;gt;x_{m_{z \, \bmod \, p = j}}, z = \overline {0, k-1},&amp;lt;/math&amp;gt; в ответ на шаг 2.2;&lt;br /&gt;
## вычислить минимальное среди полученных значений целевой функции;&lt;br /&gt;
## запомнить &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, на которых минимальное значение было достигнуто;&lt;br /&gt;
## при &amp;lt;math&amp;gt;j \neq 0 &amp;lt;/math&amp;gt; отправить тройку &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}, x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, соответствующую выбранной паре, процессу с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
# для процесса с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;:&lt;br /&gt;
## принять тройки от процессов &amp;lt;math&amp;gt;(0, min(k-1, p-1)],&amp;lt;/math&amp;gt; в ответ на шаг 3.4;&lt;br /&gt;
## найти пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, для которой целевая функция принимает минимальное значение;&lt;br /&gt;
## сравнить найденное минимальное значение с вычисленным значением целевой функции на предыдущей итерации фазы SWAP;&lt;br /&gt;
### (&#039;&#039; &#039;&#039;&#039;условие останова&#039;&#039;&#039; &#039;&#039;) если значение целевой функции не уменьшилось, остановить вычисление;&lt;br /&gt;
### иначе, разослать выявленную пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; при помощи широковещательной рассылки;&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; в ответ на шаг 4.3.2;&lt;br /&gt;
## скорректировать локальные копии множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt;, заменяя элемент &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; на элемент &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; и наоборот;&lt;br /&gt;
## перейти к шагу 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Ограничения и недостатки =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Ограничения&#039;&#039;:&lt;br /&gt;
* предполагается, что матрица расстояний &amp;lt;math&amp;gt;D^{n * n}&amp;lt;/math&amp;gt; полностью помещается в памяти каждого процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Недостатки&#039;&#039;:&lt;br /&gt;
* при распределении обсчитываемых целевых функций, каждому из процессов ставится в соответствие некоторая совокупность пар &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, для которых нужно рассчитать значения целевой функции. В случае, если количество процессов не кратно количеству обрабатываемых кластеров, различные процессы получат пары у которых совпадают &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt;, что приведёт к совершению одинаковых вычислений на различных процессах: &amp;lt;math&amp;gt;   \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )), 1 \leq j \leq n;&amp;lt;/math&amp;gt;&lt;br /&gt;
* вычисление фазы SWAP успешно распараллеливается между &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессами, однако после этого происходит агрегация данных в 2 этапа относительно &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; для вычисления глобального минимума. На первом этапе данные собираются на первых &amp;lt;math&amp;gt;\min (p,k)&amp;lt;/math&amp;gt; процессах, где происходят локальные вычисления минимумов среди принятых данных (для каждого &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt;), после чего полученные минимумы и связанная с ними информация агрегируются на мастер-процессе, который вычисляет глобальный минимум и извещает о нём все остальные процессы. &amp;lt;br&amp;gt;Во время описанных вычислений все незадействованные процессы простаивают.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Дополнительные возможности&#039;&#039;:&lt;br /&gt;
* помимо описанной схемы, также есть возможность распараллелить операцию вычисления матрицы расстояний &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, однако это является отдельной алгоритмической задачей и не даёт существенного прироста производительности алгоритма.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Существующие параллельные реализации алгоритма PAM ====&lt;br /&gt;
&lt;br /&gt;
Примером другой параллельной реализации алгоритма PAM может служить реализация в пакете SPRINT для языка R (подробнее см. [[#Существующие реализации алгоритма|существующие реализации алгоритма]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Структура графа алгоритма (см. 1.7 [[#Информационный граф| Информационный граф алгоритма]]) такова, что позволяет надеяться на получение хорошей масштабируемости.&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма Partitioning Around Medoids проводилось на суперкомпьютере BlueGene/P &amp;lt;ref&amp;gt;IBM BlueGene/P  - [http://hpc.cmc.msu.ru http://hpc.cmc.msu.ru]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Отметим, что для данному суперкомпьютеру свойственна стабильность по времени вычисления одной и той же задачи при различных запусках.&lt;br /&gt;
Во время вычислений каждому MPI процессу соответствовало 1 ядро процессора PowerPC 450, 850 MHz с пиковой производительностью 3.4 GFlop/sec per core.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
* число процессов (p):&lt;br /&gt;
** [1; 4 : 512] с шагом 4 процесса;&lt;br /&gt;
* размер кластеризуемого множества (n):&lt;br /&gt;
** [4; 16; 32; 64];&lt;br /&gt;
** [128 : 3200] с шагом 128 элементов;&lt;br /&gt;
* каждому размеру кластеризуемого множества соответствует количество кластеров для разбиения (k):&lt;br /&gt;
** [2; 4; 4; 8];&lt;br /&gt;
** [2 : 50] с шагом 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Особенности проведения эксперимента:&lt;br /&gt;
* тестовые данные являются псевдослучайными;&lt;br /&gt;
* для всех экспериментов использовался одинаковый набор данных;&lt;br /&gt;
* в соответствии с описанными параметрами запуска, для множеств размерности [128 : 3200], количество кластеров (k) прямо пропорционально размеру задачи (n).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен широкий диапазон [[Глоссарий#Эффективность распараллеливания|эффективности реализации]] алгоритма:&lt;br /&gt;
* минимальная эффективность реализации: &amp;lt;math&amp;gt;3.4 * 10^{-9} \, %&amp;lt;/math&amp;gt; достигается при использовании 512 процессов для множества из 4 элементов и 2-х кластеров (результат вызван избыточностью количества процессов по отношению к размеру задачи);&lt;br /&gt;
* максимальная эффективность реализации: &amp;lt;math&amp;gt;4.1 * 10^{-4} \, %&amp;lt;/math&amp;gt; достигается при использовании 4 процессов для множества из 128 элементов и 2 кластеров.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Абсолютная величина [[Глоссарий#Производительность|производительности алгоритма]] (GFlops) определялась как количество операций с плавающей точкой за секунду. Точное количество операций было вычислено на основании [[#Последовательная сложность алгоритма| последовательной сложности алгоритма]], целочисленные операции и операции работы с памятью не учитывались.&lt;br /&gt;
&lt;br /&gt;
Таким образом, производительность обусловлена как самим алгоритмом (его внутренняя структура определяет соотношение между операциями работы с памятью, операциями над целочисленными значениями и значениями с плавающей точкой), так и используемой реализацией.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации PAM в зависимости от изменяемых параметров запуска:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;margin: 0 auto;&amp;quot;&lt;br /&gt;
 | [[file:PAM-gflops.png|thumb|none|600px|Рисунок 5а. Параллельная реализация алгоритма PAM. Изменение производительности в зависимости от числа процессов и размера множества.]]&lt;br /&gt;
 | [[file:PAM-gflops-top-view.png|thumb|none|600px|Рисунок 5б. Параллельная реализация алгоритма PAM. Изменение производительности в зависимости от числа процессов и размера множества. Вид сверху.]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
[[file:PAM-gflops.png|thumb|center|800px|Рисунок 5а. Параллельная реализация алгоритма PAM. Изменение производительности в зависимости от числа процессов и размера множества.]]&lt;br /&gt;
[[file:PAM-gflops-top-view.png|thumb|center|800px|Рисунок 5б. Параллельная реализация алгоритма PAM. Изменение производительности в зависимости от числа процессов и размера множества. Вид сверху.]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
[[file:PAM-efficiency.png|thumb|center|800px|Рисунок 6. Параллельная реализация алгоритма PAM. Изменение эффективности в зависимости от числа процессов и размера множества.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рисунке 5б, видно, что пики организованы в прямые. Это обусловлено инвариантностью величины &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; в соответствии с описанной в [[#Вычислительное ядро алгоритма | вычислительном ядре фазы SWAP]] оптимизацией. На рисунке 3 для [[#Информационный граф фазы SWAP| информационного графа фазы SWAP]] наглядно видно, что при построчном распределении вычислений &amp;lt;math&amp;gt;\overline{b}_{x_{m_s, o_h}}&amp;lt;/math&amp;gt; возможно возникновение следующих ситуаций (далее при &#039;&#039; &#039;&#039;&#039;k * (n-k) mod p == 0&#039;&#039;&#039; &#039;&#039; обозначим &#039;&#039; &#039;&#039;&#039;r = k * (n-k) / p&#039;&#039;&#039; &#039;&#039;):&lt;br /&gt;
# при &#039;&#039; &#039;&#039;&#039;r &amp;lt; (n-k)&#039;&#039;&#039; &#039;&#039;, если &#039;&#039; &#039;&#039;&#039;(n-k) mod r == 0&#039;&#039;&#039; &#039;&#039;, то каждому процессу необходимо вычислить ровно одну величину &amp;lt;math&amp;gt;\overline{a}_{x_{m_s}};&amp;lt;/math&amp;gt;&lt;br /&gt;
# при &#039;&#039; &#039;&#039;&#039;r &amp;amp;ge; (n-k)&#039;&#039;&#039; &#039;&#039;, если &#039;&#039; &#039;&#039;&#039;k mod p == 0&#039;&#039;&#039; &#039;&#039;, то каждому процессу необходимо вычислить несколько соответствующих ему величин &amp;lt;math&amp;gt;\overline{a}_{x_{m_s}},&amp;lt;/math&amp;gt; при этом каждая величина будет вычислена ровно в одном процессе;&lt;br /&gt;
# в остальных случаях вычисления величин &amp;lt;math&amp;gt;\overline{b}_{x_{m_s, o_h}}&amp;lt;/math&amp;gt; распределяются между процессами таким образом, что часть процессов обрабатывает больше величин &amp;lt;math&amp;gt;\overline{a}_{x_{m_s}}&amp;lt;/math&amp;gt; нежели остальные (ситуация возникает при обработке процессом последних элементов одной строки и первых элементов следующей). Подобная ситуация приводит к дополнительным вычислениям на некоторых процессах и, как следствие, к простою остальных, в связи с чем происходит падение производительности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Первые два случая приводят к равномерному распределению нагрузки между процессами, и им соответствуют видимые пики на приведённых рисунках 5a, 5б, 6. Для 3-го случая из-за неравномерной загрузки процессов достигаемая производительность падает.&lt;br /&gt;
&lt;br /&gt;
Второй случай соответствует размеру задачи меньшему, чем количество процессов и на практике маловероятен.&lt;br /&gt;
Таким образом, для повышения производительности следует выбирать количество процессов так, чтобы &#039;&#039; &#039;&#039;&#039;k * (n-k)&#039;&#039;&#039; &#039;&#039; и &#039;&#039; &#039;&#039;&#039;(n-k)&#039;&#039;&#039; &#039;&#039; были кратны &#039;&#039; &#039;&#039;&#039;p&#039;&#039;&#039; &#039;&#039; и &#039;&#039; &#039;&#039;&#039;k * (n-k) div p&#039;&#039;&#039; &#039;&#039; соответственно.&lt;br /&gt;
&lt;br /&gt;
Для исследуемой реализации, вычисление величин &amp;lt;math&amp;gt;\overline{a}_{x_{m_s}}&amp;lt;/math&amp;gt; может быть оптимизировано (за счёт распределения между процессами и последующих пересылок). Однако принципиальный вид графиков останется тем же: пики будут наблюдаться для случаев равномерного распределения вычислительных задач между процессами.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости выбранной реализации алгоритма PAM:&lt;br /&gt;
* По числу процессов: &amp;lt;math&amp;gt;- \, 1.6 * 10^{-8}.&amp;lt;/math&amp;gt; С ростом числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается. Этот результат вызван ростом времени, затрачиваемого на пересылку данных, то есть ростом накладных расходов на организацию параллельного выполнения.&lt;br /&gt;
* По размеру задачи: &amp;lt;math&amp;gt;3.9 * 10^{-7}&amp;lt;/math&amp;gt;. С ростом размера задачи эффективность на рассмотренной области изменений параметров запуска увеличивается. Этот результат вызван увеличением количества вычислений относительно объема пересылок данных.&lt;br /&gt;
* Общая оценка масштабируемости: &amp;lt;math&amp;gt;- \, 1.2 * 10^{-9}&amp;lt;/math&amp;gt;. При рассмотрении области параметров запуска в целом можно говорить о том, что с ростом размера задачи и числа процессов эффективность незначительно падает.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/phonexicum/pam-mpi-cmc Исследованная параллельная реализация на языке C++] (реализация написана самостоятельно)&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# Последовательная реализация алгоритма PAM в пакете ClusterR на языке R:&lt;br /&gt;
#* Лицензия: MIT&lt;br /&gt;
#* [https://cran.r-project.org/package=ClusterR веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в функции &#039;Cluster_Medoids&#039;. Отличительная особенность реализации &amp;lt;ref&amp;gt;Lampros Mouselimis [https://cran.r-project.org/web/packages/cluster/cluster.pdf Package &#039;ClusterR&#039;]. October 8, 2016&amp;lt;/ref&amp;gt;:&lt;br /&gt;
#** для задания метрики между элементами кластеризуемого множества передаётся строка, задающая одну из реализованных в алгоритме метрик. Данный подход теряет одно из преимуществ алгоритма PAM, позволяющее в качестве матрицы расстояний использовать произвольную матрицу различий.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Последовательная реализация алгоритма PAM в пакете Cluster на языке R:&lt;br /&gt;
#* Лицензия: GPL (≥2)&lt;br /&gt;
#* [https://cran.r-project.org/package=cluster веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в функции &#039;pam()&#039;. Данная реализация имеет следующие особенности &amp;lt;ref&amp;gt;Martin Maechler., etc. [https://cran.r-project.org/web/packages/cluster/cluster.pdf Package &#039;cluster&#039;]. October 8, 2016&amp;lt;/ref&amp;gt;:&lt;br /&gt;
#** функция может принимать на вход не множество точек, а матрицу расстояний между ними;&lt;br /&gt;
#** реализация более гибкая, так как принимает на вход матрицу различий элементов, а не использует какую-либо метрику;&lt;br /&gt;
#** может быть предоставлено графическое отображение.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Параллельная реализация алгоритма PAM в пакете SPRINT (Simple Parallel R INTerface - параллельный фреймворк) на языке R:&lt;br /&gt;
#* Лицензия: GPL (≥3)&lt;br /&gt;
#* [https://cran.r-project.org/package=sprint веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в фукции &#039;ppam()&#039;. Входные параметры данной функции схожи с параметрами, задаваемыми в линейной реализации &#039;pam()&#039; пакета Cluster языка R. Отличительной особенностью является подача на вход предвычисленной матрицы расстояний (например, с помощью функции &#039;pcor()&#039; из этой же библиотеки).&amp;lt;ref&amp;gt;University of Edinburgh SPRINT Team. [https://cran.r-project.org/web/packages/sprint/sprint.pdf Package &#039;sprint&#039;]. February 20, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Параллельная реализация алгоритма PAM на основе операций MapReduce на Hadoop кластере.&lt;br /&gt;
#* В рамках исследования по ускорению анализа информации о геноме были созданы реализации алгоритма PAM с использованием технологии MPI и технологии MapReduce. Реализация в открытом досупе отсутствует. &amp;lt;ref&amp;gt;Dobrzelecki B. et al. Managing and analysing Genomic Data using HPC and Clouds //Grid and Cloud Database Management. – Springer Berlin Heidelberg, 2011. – С. 261-277.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
MKL, ScaLAPACK, PETSc, FFTW, ATLAS, Magma и другие подобные библиотеки.&lt;br /&gt;
&lt;br /&gt;
* Дать ссылки на существующие последовательные и параллельные реализации алгоритма (&amp;quot;уже доступные&amp;quot;)&lt;br /&gt;
* Реализация - коммерческая/свободная, лицензия&lt;br /&gt;
* ссылка на дистрибутив и описание&lt;br /&gt;
* особенности, достоинства/недостатки, ....&lt;br /&gt;
&lt;br /&gt;
гугл-запрос: &amp;quot;partitioning around medoids&amp;quot; &amp;quot;PAM&amp;quot; BUILD SWAP &amp;quot;MPI&amp;quot; &amp;quot;program&amp;quot; &amp;quot;package&amp;quot; -worldwidescience&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Anastasia</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:Avasilenko&amp;diff=17648</id>
		<title>Обсуждение участника:Avasilenko</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:Avasilenko&amp;diff=17648"/>
		<updated>2016-11-16T12:28:16Z</updated>

		<summary type="html">&lt;p&gt;Anastasia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;п. 2.4&lt;br /&gt;
&lt;br /&gt;
* не указано, какая реализация алгоритма использовалась - собственная или библиотечная&lt;br /&gt;
*: [[Участник:Zhum|Zhum]] ([[Обсуждение участника:Zhum|обсуждение]]) 11:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** &#039;&#039;Ссылкка на реализацию была указана в конце параграфа. Явно добавили указание, что реализация собственная.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Anastasia</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:Avasilenko/Partitioning_Around_Medoids_(PAM)&amp;diff=17645</id>
		<title>Участник:Avasilenko/Partitioning Around Medoids (PAM)</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:Avasilenko/Partitioning_Around_Medoids_(PAM)&amp;diff=17645"/>
		<updated>2016-11-16T12:24:09Z</updated>

		<summary type="html">&lt;p&gt;Anastasia: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Partitioning Around Medoids&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(T*kn^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*(n-1)+2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;k+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(T*kn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(k(n-k))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Авторы&#039;&#039;&#039;:&lt;br /&gt;
* [[Участник:Avasilenko|А.Э.Василенко]] (отвечает за программистскую составляющую);&lt;br /&gt;
* [[Участник:Anastasia|А.В.Тузикова]] (отвечает за математическую составляющую).&lt;br /&gt;
Вклад авторов считать равноценным, чётких границ ответственности провести невозможно.&lt;br /&gt;
&lt;br /&gt;
==Свойства и структура алгоритма==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
 &lt;br /&gt;
Объединение схожих объектов в группы - один из важнейших видов человеческой деятельности&amp;lt;ref&amp;gt;Rousseeuw P. J., Kaufman L. Finding Groups in Data. – Wiley Online Library, 1990.&amp;lt;/ref&amp;gt;. Более того - это важная часть процесса познания мира, в котором мы живем. Мы учим детей различать кошек и собак, воду и песок, мужчин и женщин путем постоянного развития и улучшения подсознательных схем классификации. Примеры есть и во взрослой жизни – в химии необходимо классифицировать соединения, в археологии – объединять находки по периодам и т.д.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задача кластеризации&#039;&#039;&#039; - разделение множества объектов на заданное число множеств с минимизацией некоторого функционала - является популярной задачей, относится к разделу машинного обучения и находит применение в таких областях, как анализ текста, биоинформатика, интеллектуальные транспортные системы и др. &amp;lt;ref&amp;gt; Речкалов Т.В. Параллельный алгоритм кластеризации для многоядерного сопроцессора Intel Xeon Phi // Суперкомпьютерные дни в России: Труды vеждународной конференции. – М.: Изд-во МГУ, 2015, c. 532.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существует несколько видов кластеризации&amp;lt;ref&amp;gt;Маннинг К.Д., Введение в информационный поиск: пер. с англ. / К.Д. Маннинг, П. Рагхаван, Х.Шютце - М. : Вильямс, 2011. - 528.&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;плоская кластеризация&#039;&#039; (&#039;&#039;flat clustering&#039;&#039;) - порождает совокупность кластеров, не имеющих явных взаимосвязей;&lt;br /&gt;
* &#039;&#039;иерархическая кластеризация&#039;&#039; (&#039;&#039;hierarchical clustering&#039;&#039;) - создаёт иерархию кластеров.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PAM&#039;&#039;&#039; (&#039;&#039;&#039;Partitioning Around Medoids&#039;&#039;&#039;) - плоский алгоритм кластеризации, позволяющий выделить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров (множеств), удовлетворяющих следующим свойствам:&lt;br /&gt;
 &lt;br /&gt;
*   каждая группа содержит хотя бы один объект;&lt;br /&gt;
*   каждый объект принадлежит ровно одной группе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Модель &amp;lt;ref&amp;gt;Kaufman, L. and Rousseeuw, P.J., Clustering by means of Medoids. In: Y. Dodge and North-Holland, editor. Statistical Data Analysis Based on the L1-Norm and Related Methods. Springer US; 1987, p. 405–416.&amp;lt;/ref&amp;gt;, лежащая в основе алгоритма PAM, основана на выборе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов, являющихся характерными точками соответствующего кластера. Таким образом, кластерам сопоставляются принадлежащие им объекты, называемые &#039;&#039;&#039;медоидами&#039;&#039;&#039;, на основании которых распределяются остальные объекты по принципу наибольшего сходства. Cама модель называется моделью &#039;&#039;&#039;k-medoids&#039;&#039;&#039; (не путать с моделью &#039;&#039;k-median&#039;&#039;).&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
PAM состоит из двух фаз: &#039;&#039;&#039;BUILD&#039;&#039;&#039; и &#039;&#039;&#039;SWAP&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
*   на фазе BUILD выполняется первичная кластеризация, в ходе которой последовательно выбираются &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов в качестве медоидов;&lt;br /&gt;
*   фаза SWAP представляет собой итерационный процесс, в ходе которого производятся попытки улучшить множество медоидов. Алгоритм выполняет поиск пары объектов (медоид, не-медоид), минимизирующих целевую функцию при замене, после чего обновляет множество медоидов.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации алгоритма выбирается пара (медоид, не-медоид) такая, что замена медоида &amp;lt;math&amp;gt;x_{m_l}&amp;lt;/math&amp;gt; на не-медоид &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; дает лучшую кластеризацию из возможных. Оценка кластеризации выполняется с помощью целевой функции, вычисляемой как сумма расстояний от каждого объекта до ближайшего медоида:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum_{j = 1}^n \min_{1 \leq l \leq k} \rho ( x_{m_l},x_{o_h} )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура изменения множества медоидов повторяется, пока есть возможность улучшения значения целевой функции.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Исходные данные&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
*   множество кластеризуемых объектов &amp;lt;math&amp;gt;X = \{ x_1, x_2, ... , x_n \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; - кортеж, состоящий из &amp;lt;math&amp;gt; w &amp;lt;/math&amp;gt; вещественных чисел;&lt;br /&gt;
*   симметрическая матрица &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, элементы матрицы &amp;lt;math&amp;gt;d_{ij}=d(i,j)&amp;lt;/math&amp;gt; - вычисленные расстояния между объектами &amp;lt;math&amp;gt;x_i, x_j&amp;lt;/math&amp;gt;;&lt;br /&gt;
*   количество кластеров &amp;lt;math&amp;gt;k \leq n.&amp;lt;/math&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Обозначения&#039;&#039;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;M = \{ x_{m_1}, x_{m_2}, ... , x_{m_k} \} &amp;lt;/math&amp;gt; - множество медоидов, &amp;lt;math&amp;gt; M \subseteq X ;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;O = \{ x_{o_1}, x_{o_2}, ... , x_{o_r} \} &amp;lt;/math&amp;gt; - множество не-медоидов, &amp;lt;math&amp;gt; O \subseteq X, &amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;r=n-k;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;d_{ij}=\rho (x_i, x_j )&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \rho  : X \times X \rightarrow R &amp;lt;/math&amp;gt; — метрика расстояния;&lt;br /&gt;
*   &amp;lt;math&amp;gt;F_{M,O} = \sum_{j = 1}^{n} \min_{ x_{m_l} \in M} \rho ( x_{m_l},x_{o_j} )&amp;lt;/math&amp;gt; - значение целевой функции для заданных множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;T^i&amp;lt;/math&amp;gt; - изменение целевой функции на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-м шаге фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Выходные данные&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;M = \{ x_{m_1}, x_{m_2}, ... , x_{m_k} \}&amp;lt;/math&amp;gt; - множество медоидов;&lt;br /&gt;
* &amp;lt;math&amp;gt;K_{m_i} = \{ x_{o_h} \in O \| x_{m_i} = \arg \min_{x_{m_s} \in M} \rho (x_{o_h}, x_{m_s}) \}, 1 \leq i \leq k&amp;lt;/math&amp;gt; - искомые кластеры.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Вычислительные формулы метода&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
*   &#039;&#039;фаза BUILD&#039;&#039; (состоит из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; шагов последовательного выбора &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; медоидов):&lt;br /&gt;
**   &amp;lt;math&amp;gt;O_0 = X, M_0 = \varnothing ;&amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_1} = \arg \min_{x_{o_h} \in O_0} \sum_{j = 1}^n \rho \left ( x_{o_h},x_j \right ), O_1 = O_0 \backslash \{x_{m_1}\}, M_1 = M_1 \cup \{x_{m_1}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_2} = \arg \min_{x_{o_h} \in O_1} \sum_{j = 1}^{n} \min ( \rho ( x_{m_1},x_j ), \rho ( x_{o_h},x_j ) ), O_2 = O_1 \backslash \{x_{m_2}\}, M_2 = M_1 \cup \{x_{m_2}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_3} = \arg \min_{x_{o_h} \in O_2} \sum_{j = 1}^{n} \min_{1 \leq l \leq 2} ( \rho ( x_{m_l},x_j ) , \rho ( x_{o_h},x_j ) ) , O_3 = O_2 \backslash \{x_{m_3}\}, M_3 = M_3 \cup \{x_{m_3}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
** ...&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_k} = \arg \min_{x_{o_h} \in O_{k-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{k-1}} ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j ) ) , O_k = O_{k-1} \backslash \{x_{m_k}\}, M_k = M_{k-1} \cup \{x_{m_k}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;фаза SWAP&#039;&#039; (итерационный процесс):&lt;br /&gt;
** начальное приближение: &amp;lt;math&amp;gt;O_0 = O_k^{BUILD}, M_0 = M_k^{BUILD};&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й шаг итерации:&lt;br /&gt;
*** вычисление целевой функции при оптимальной замене (замене, при которой достигается лучшая кластеризация из возможных на текущей итерации): &amp;lt;br&amp;gt;&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j) ); &amp;lt;/math&amp;gt;&lt;br /&gt;
*** определение пары (медоид, не-медоид), на которой достигается оптимальная замена: &amp;lt;br&amp;gt;&amp;lt;math&amp;gt; (x_{m_s}, x_{o_h}) = \arg F^i; &amp;lt;/math&amp;gt;&lt;br /&gt;
*** проверка критерия останова;&lt;br /&gt;
*** изменение множеств в соответствии с выбранной парой &amp;lt;math&amp;gt; (x_{m_s}, x_{o_h}):&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&amp;lt;math&amp;gt;M_i = M_{i-1} \backslash \{x_{m_s}\} \cup \{x_{o_h}\} , O_i = O_{i-1} \cup \{x_{m_s}\} \backslash \{x_{o_h}\} ;&amp;lt;/math&amp;gt;&lt;br /&gt;
** критерий останова:&lt;br /&gt;
*** &amp;lt;math&amp;gt;T^i = F^{i-1} - F^{i} \leq 0 .&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро алгоритма PAM на этапе BUILD&#039;&#039;&#039; состоит из многочисленных вычислений значений целевой функции при различных вариантах выбора дополнительного медоида (шаг алгоритма &amp;lt;math&amp;gt;1 \leq i \leq k&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1}} ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j ) ) = \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \overline{MIN}_{i, x_{o_h}}^{(j)},&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;\overline{MIN}_{1, x_{o_h} \in O_0} = \{ \rho (x_{o_h}, x_j ) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{o_h} \in O_{i-1}} = \{ \min ( \overline{MIN}_{i-1, x_{m_{i-1}}}^{(j)}, \rho (x_{o_h}, x_j) ) \| 1 \leq j \leq n \}, \forall i: 1 &amp;lt; i \leq k.&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;|O_{i-1}| = n-i+1&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Оптимизация&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* таким образом, на каждой последующей итерации можно использовать величину, вычисленную на предыдущем шаге, что позволяет сократить число вычислений минимумов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро алгоритма PAM на этапе SWAP&#039;&#039;&#039; состоит из многочисленных вычислений значений целевой функции при различных вариантах замены некоторого существующего медоида на элемент из числа не-медоидов. &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-я итерация фазы SWAP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j) ) =&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;= \min_{x_{m_s} \in M_{i-1} } \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Оптимизация&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* таким образом, при поиске пары (медоид, не-медоид), наилучшим образом минимизирующей целевую функцию, происходит поиск минимума по всем возможным элементам &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, для которых вычисляется &amp;lt;math&amp;gt;\sum_{j = 1}^{n} \min (a, b)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt; \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )),&amp;lt;/math&amp;gt; и является инвариантом по отношению к &amp;lt;math&amp;gt;\min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) ),&amp;lt;/math&amp;gt; что позволяет предвычислить элемент &amp;lt;math&amp;gt;a.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Опишем макрооперации алгоритма&#039;&#039;:&lt;br /&gt;
* в случае если алгоритму PAM на вход подаётся набор точек с их координатами в пространстве &amp;lt;math&amp;gt;R^w,&amp;lt;/math&amp;gt; то необходимо вычислить матрицу расстояний. Для этого может быть использована, например, евклидова метрика:&lt;br /&gt;
*: &amp;lt;math&amp;gt;\rho (p,q)=\sqrt{(p_1-q_1)^2+(p_2-q_2)^2+\dots+(p_w-q_w)^2} = \sqrt{\sum_{j=1}^w (p_j-q_j)^2} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p, q \in R^w;&amp;lt;/math&amp;gt;&lt;br /&gt;
* нахождение минимального среди значений, принимаемых некоторой функцией &amp;lt;math&amp;gt;value,&amp;lt;/math&amp;gt; определённой на дискретном множестве &amp;lt;math&amp;gt;Y=\{y_i\}, \, i = \overline{(1,r)}:&amp;lt;/math&amp;gt;&lt;br /&gt;
*: &amp;lt;math&amp;gt;minimum_{y \in Y } (value (y)) = \min \Bigg(value(y_1), \min \bigg(value(y_2), \min \Big(\dots , \min(value(y_{r-1}), value(y_{r})) ... \Big) \bigg)\Bigg);&amp;lt;/math&amp;gt;&lt;br /&gt;
* вычисление вектора инвариантов, используемых при оптимизации фазы SWAP (см. вычислительное ядро алгоритма):&lt;br /&gt;
*: &amp;lt;math&amp;gt;\overline{a} = \{ minimum_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l}, x_j ) ) \| 1 \leq j \leq n \},&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;i - &amp;lt;/math&amp;gt;номер итерации;&lt;br /&gt;
* вычисление вектора расстояний от каждой точки заданного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; до ближайшего медоида из множества &amp;lt;math&amp;gt;M_{i-1} \backslash \{x_{m_s}\},&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;i - &amp;lt;/math&amp;gt;номер итерации фазы SWAP: &lt;br /&gt;
*: &amp;lt;math&amp;gt;\overline{b} = \{ \min (\overline{a}^{(j)}, \rho ( x_{o_p}, x_j )) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
* сложение компонент вектора: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline{f}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Макроструктура вычислительного ядра алгоритма PAM&#039;&#039; может быть выражена через макрооперации следующим образом:&lt;br /&gt;
* для ядра фазы BUILD:&lt;br /&gt;
*::: &amp;lt;math&amp;gt;F^i = minimum_{ x_{o_h} \in O_{i-1} } ( S \, ( \overline{f} (x_{o_h}) )),&amp;lt;/math&amp;gt;&lt;br /&gt;
*::: &amp;lt;math&amp;gt;\overline{f} = \{ \min \,( \overline{MIN}_{i, x_{o_h}}^{(j)}, \rho (x_{o_h}, x_j)) \| 1 \leq j \leq n \}, &amp;lt;/math&amp;gt; где&lt;br /&gt;
*# &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;n-i+1&amp;lt;/math&amp;gt; раз;&lt;br /&gt;
*# &amp;lt;math&amp;gt;minimum&amp;lt;/math&amp;gt; находится &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; раз при вычислении наилучшего значения целевой функции на текущей итерации.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* для ядра фазы SWAP:&lt;br /&gt;
*::: &amp;lt;math&amp;gt;F^i = minimum_{ x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1} } ( S \, ( \overline{b} \, ( x_{o_h}, \overline{a} \, (x_{m_s}) ) )),&amp;lt;/math&amp;gt; где:&lt;br /&gt;
*# &amp;lt;math&amp;gt;minimum&amp;lt;/math&amp;gt; находится &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; раз  в процессе вычисления макрооперации &amp;lt;math&amp;gt;\overline {a};&amp;lt;/math&amp;gt;&lt;br /&gt;
*# &amp;lt;math&amp;gt;\overline {a}&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; раз и использует вычисленные на шаге 1 минимальные значения;&lt;br /&gt;
*# &amp;lt;math&amp;gt;\overline {b}&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;k(n-k)&amp;lt;/math&amp;gt; раз и использует вычисленные на шаге 2 значения &amp;lt;math&amp;gt;\overline {a};&amp;lt;/math&amp;gt;&lt;br /&gt;
*# &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;k(n-k)&amp;lt;/math&amp;gt; раз и использует вычисленные на шаге 3 значения &amp;lt;math&amp;gt;\overline {b};&amp;lt;/math&amp;gt;&lt;br /&gt;
*# &amp;lt;math&amp;gt;minimum&amp;lt;/math&amp;gt; находится &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; раз при вычислении наилучшего значения целевой функции на текущей итерации.&lt;br /&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;&#039;&#039;  : Множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; или матрица расстояний &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, количество кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;&lt;br /&gt;
 &#039;&#039;&#039;Выход&#039;&#039;&#039; : Множество медоидов &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
 0  Если на вход было подано множество объектов, необходимо предварительно вычислить матрицу расстояний;&lt;br /&gt;
 1  Инициализация множеств &amp;lt;math&amp;gt;M := \varnothing, O := X;&amp;lt;/math&amp;gt;&lt;br /&gt;
 &amp;amp;nbsp;&lt;br /&gt;
    // фаза BUILD&lt;br /&gt;
 2  &#039;&#039;&#039;for (int i := 1; i &amp;lt;= k; i++)&#039;&#039;&#039; {&lt;br /&gt;
        // Найти &amp;lt;math&amp;gt;x_{m_i}:&amp;lt;/math&amp;gt;&lt;br /&gt;
        {&lt;br /&gt;
 3          Для всех &amp;lt;math&amp;gt;x_{o_h} \in O&amp;lt;/math&amp;gt; вычислить &amp;lt;math&amp;gt;F_{M \cup \{x_{o_h}\}, O \backslash \{x_{o_h}\}};&amp;lt;/math&amp;gt;&lt;br /&gt;
 4          Положить &amp;lt;math&amp;gt;x_{m_i}&amp;lt;/math&amp;gt; равным &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, соответствующему минимальному из вычисленных &amp;lt;math&amp;gt;F;&amp;lt;/math&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
 5      Обновить множества &amp;lt;math&amp;gt;M := M \cup \{x_{m_i}\}, O := O \backslash \{x_{m_i}\};&amp;lt;/math&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
    // фаза SWAP&lt;br /&gt;
 6  &#039;&#039;&#039;while (1)&#039;&#039;&#039; {&lt;br /&gt;
        // Найти пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h}),&amp;lt;/math&amp;gt; на которой достигается оптимальная замена:&lt;br /&gt;
        {&lt;br /&gt;
 7          Для всех &amp;lt;math&amp;gt;x_{m_i} \in M, x_{o_j} \in O&amp;lt;/math&amp;gt; вычислить &amp;lt;math&amp;gt;F^i;&amp;lt;/math&amp;gt; // вычисление проводить с учётом приведённой ранее оптимизации (см. 1.3 [[#Вычислительное ядро алгоритма|Вычислительное ядро алгоритма]]);&lt;br /&gt;
 8          Положить пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; равной паре &amp;lt;math&amp;gt;(x_{m_i}, x_{o_j})&amp;lt;/math&amp;gt;, соответствующей минимальному из вычисленных &amp;lt;math&amp;gt;F;&amp;lt;/math&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
 9      Вычислить &amp;lt;math&amp;gt;T^i;&amp;lt;/math&amp;gt; // критерий останова (см. 1.2 [[#Математическое описание алгоритма|Математическое описание алгоритма]])&lt;br /&gt;
 10     &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;(T^i &amp;gt; 0)&amp;lt;/math&amp;gt; {&lt;br /&gt;
 11         Обновить множества &amp;lt;math&amp;gt;M := M \backslash \{x_{m_s}\} \cup \{x_{o_h}\}, O := O \cup \{x_{m_s}\} \backslash \{x_{o_h}\};&amp;lt;/math&amp;gt;&lt;br /&gt;
 12     } &#039;&#039;&#039;else&#039;&#039;&#039; {&lt;br /&gt;
 13         &#039;&#039;&#039;break&#039;&#039;&#039;;&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;&#039;&#039;. Необходимо предварительно вычислить матрицу расстояний и сохранить её в памяти, так как в ходе вычисления алгоритма многократно используются расстояния между элементами, а вычисление каждого из них является ресурсоёмкой операцией из нескольких умножений и одного извлечения квадратного корня.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Минимизация кеш-промахов&#039;&#039;&#039;. Матрица расстояний, к которой постоянно выполняется доступ на чтение для вычисления минимумов и их суммирования, должна храниться в памяти как матрица размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, несмотря на то, что она симметрическая и достаточно хранить лишь половину (элементы над или под главной диагональю). Данная оптимизация потребует использования в 2 раза большего количества памяти для хранения расстояний (а это является главным расходом памяти программы, так как все остальные используемые данные являются временными (локальными для каждой операции) и представляют из себя несколько векторов длинной &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов). Однако так как в данном алгоритме доступ к матрице осуществляется построчно (в  [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]] поэлементно ищутся  минимумы 2-х векторов, после чего все они складываются), то в этом случае из матрицы можно будет читать данные по строкам подряд, что снижает количество кеш-промахов. Использование только половины матрицы приводит к частым промахам в кеше в связи с необходимостью загрузки части векторов по строкам, а части - по столбцам.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления &#039;&#039;&#039;матрицы расстояний&#039;&#039;&#039; требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций вычисления расстояний;&lt;br /&gt;
* сложность каждой операции вычисления расстояния (для случая использования Евклидовой метрики) равна &amp;lt;math&amp;gt;2*w-1&amp;lt;/math&amp;gt; операций сложения и вычитания, &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; операций возведения в квадрат (умножения) и &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операции извлечения квадратного корня.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основании формулы из описания &#039;&#039;&#039;вычислительного ядра фазы BUILD&#039;&#039;&#039; определим сложность выполнения всего этапа.&lt;br /&gt;
&lt;br /&gt;
Обозначим:&lt;br /&gt;
*&amp;lt;math&amp;gt;summs&amp;lt;/math&amp;gt; - операция сложения двух вещественных чисел;&lt;br /&gt;
*&amp;lt;math&amp;gt;mins&amp;lt;/math&amp;gt; - операция нахождения минимума для двух вещественных чисел.&lt;br /&gt;
&lt;br /&gt;
Тогда, количество операций равно:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = ( ( (n-1) summs ) * (n-1+1) + (n-1+1-1)mins) + \sum_{i = 2}^{k} ( ( (1 mins)*(n-1) + (n-1) summs ) * (n-i+1) + (n-i+1-1)mins) \Rightarrow&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Rightarrow S =&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = ( ( 0 ) * (n-1+1) + (n-1+1-1)mins) + \sum_{i = 2}^{k} ( ( (1 mins)*(n-1)) * (n-i+1) + (n-i+1-1)mins ) &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = \sum_{i = 1}^{k} ( ( (n-1) summs ) * (n-i+1) ) &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
=&lt;br /&gt;
&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
=&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = n^2(k-1) - \frac{1}{2}(nk^2 - nk) + n - k &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = n^2k - \frac{1}{2}(nk^2 + nk - k^2 + k ) &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность фазы BUILD есть &amp;lt;math&amp;gt;O(kn^2)&amp;lt;/math&amp;gt; как по количеству найденных минимумов, так и по количеству операций сложения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основании формулы из описания &#039;&#039;&#039;вычислительного ядра фазы SWAP&#039;&#039;&#039; определим сложность вычисления целевой функции &amp;lt;math&amp;gt;F^i&amp;lt;/math&amp;gt; с использованием оптимизации процесса нахождения минимума (см. раздел [[#Вычислительное ядро алгоритма|Вычислительное ядро алгоритма]]). Количество операций равно:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = ( ( (1 mins)*(n-1) + (n-1) summs )*(n-k) + n*((k-1-1) mins) )*k \Rightarrow&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Rightarrow S =&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = ( ((1 mins)*(n-1) )*(n-k) + n*((k-1-1) mins) )*k = kn^2 - 3nk + k^2 &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = ( ( (n-1) summs )*(n-k) )*k = (n-1)(n-k)k &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность одной итерации фазы SWAP есть &amp;lt;math&amp;gt;O(kn^2)&amp;lt;/math&amp;gt; как по количеству найденных минимумов, так и по количеству операция сложения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Полученные оценки позволяют говорить о том, что PAM относится к алгоритмам &#039;&#039;&#039;с квадратичной сложностью&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Основная вычислительная сложность алгоритма PAM приходится на фазу SWAP, т.к. сложность одной её итерации сопоставима со сложностью всей фазы BUILD, однако SWAP может содержать в себе огромное число итераций.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
==== Информационный граф фазы BUILD ====&lt;br /&gt;
 &lt;br /&gt;
Опишем граф фазы BUILD как аналитически, так и в виде рисунка.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Граф состоит из шести групп вершин&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
# Операция M, соответствующая &#039;&#039;&#039;первой&#039;&#039;&#039; группе вершин, осуществляет изменение множества медоидов:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M_{It} = M_{It-1} \cup \overline{x}_{m_{It}}, &amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;\overline{x}_{m_{It}} = \overline{x}_{o_{It}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; (номер итерации), соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_{It}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M_{It-1}&amp;lt;/math&amp;gt; - множество медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It \leq k &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция O, соответствующая &#039;&#039;&#039;второй&#039;&#039;&#039; группе вершин, осуществляет изменение множества не-медоидов:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;O_{It} = O_{It-1} \backslash \overline{x}_{o_{It}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt;, соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_{It}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;O_{It-1}&amp;lt;/math&amp;gt; - множество не-медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It \leq k &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;третьей&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{c}=\overline{c}_{x_{o_p} } =  \begin{cases} \{ \rho (x_{o_p}, x_j ) \| 1 \leq j \leq n \}, It=1 &amp;amp; \quad\\ \{ \min ( \overline{MIN}^{(j)}, \rho (x_{o_p}, x_j) ) \| 1 \leq j \leq n \}, 1&amp;lt;It \leq k &amp;amp; \quad\\  \end{cases} .&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-It+1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = 1:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** &amp;lt;math&amp;gt;\overline{x}_{o_p}&amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;1 &amp;lt; It \leq k:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:**&amp;lt;math&amp;gt;\overline{x}_{o_p}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#:**&amp;lt;math&amp;gt;\overline{MIN}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из шестой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция S, соответствующая &#039;&#039;&#039;четвертой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline {c}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-It+1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{c}_{ x_{o_p} }&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из третьей группы с координатами &amp;lt;math&amp;gt; It, p.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M1, соответствующая &#039;&#039;&#039;пятой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M1 = (F^{It}; x_{o_{It}}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt; \begin{cases}&lt;br /&gt;
F^{It} = \min_{x_{o_p} \in O_{It-1}} S &amp;amp; \quad\\&lt;br /&gt;
x_{o_{It}} = \arg F^{It} &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из четвертой группы с первой координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;n-It+1&amp;lt;/math&amp;gt; величина.&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция MIN, соответствующая &#039;&#039;&#039;шестой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{MIN}=\overline{MIN}_{It,x_{m_{It}} } =  \begin{cases}&lt;br /&gt;
\{ \rho (x_{m_{It}            }, x_j ) \| 1 \leq j \leq n \}, It=1 &amp;amp; \quad\\&lt;br /&gt;
\{ \min ( \overline{MIN}^{(j)}, \rho (x_{m_{It}}, x_j) ) \| 1 \leq j \leq n \}, 1&amp;lt;It \leq k &amp;amp; \quad\\&lt;br /&gt;
 \end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k-1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{MIN}_{It-1,x_{m_{It-1}}} &amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из шестой группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;x_{m_{It}} =  x_{o_{It}} &amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описанный граф в общем случае представлен на Рис.1, отображен шаг с номером &amp;lt;math&amp;gt;It, 1&amp;lt;It&amp;lt;k&amp;lt;/math&amp;gt; фазы BUILD.&lt;br /&gt;
Обозначения:&lt;br /&gt;
# вершины первой группы обозначены фиолетовым цветом и подписаны как &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины  второй группы обозначены синим цветом и подписаны как &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины третьей группы обозначены жёлтым цветом и подписаны как &amp;lt;math&amp;gt;\overline{c}_{x_{o_p} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины четвертой группы обозначены серым цветом и подписаны как &amp;lt;math&amp;gt;S;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины пятой группы обозначены зеленым цветом и подписаны как &amp;lt;math&amp;gt;M1;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины шестой группы обозначены красным цветом и подписаны как &amp;lt;math&amp;gt;MIN;&amp;lt;/math&amp;gt;&lt;br /&gt;
# синим дугам сопоставлены метки, отражающие данные, используемые в соответствующих жёлтых вершинах.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Pam build 1.png|thumb|center|800px|Рисунок 1. Граф фазы BUILD алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На Рис.2 представлен граф фазы BUILD для случая &amp;lt;math&amp;gt;n=6, k=3.&amp;lt;/math&amp;gt; Вершины, соответствующие операциям, получающим входные данные и производящим выходные данные, увеличены и выделены толстыми границами.&lt;br /&gt;
&lt;br /&gt;
[[file:Pam build 2.png|thumb|center|1100px|Рисунок 2. Граф фазы BUILD алгоритма для n = 6, k = 3. ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Информационный граф фазы SWAP ====&lt;br /&gt;
 &lt;br /&gt;
Опишем граф фазы SWAP как аналитически, так и в виде рисунка.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Граф состоит из семи групп вершин&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
# Операция M, соответствующая &#039;&#039;&#039;первой&#039;&#039;&#039; группе вершин, осуществляет изменение множества медоидов.&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; (номер итерации), соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; T),&amp;lt;/math&amp;gt; принимая все целочисленные значения, где:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;T\in \N&amp;lt;/math&amp;gt; - количество выполнений фазы SWAP во время работы алгоритма PAM.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* результат срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M_{It-1}&amp;lt;/math&amp;gt; - множество медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It &amp;lt; T &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; T -1 &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = T - 1&amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы SWAP.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция O, соответствующая &#039;&#039;&#039;второй&#039;&#039;&#039; группе вершин, осуществляет изменение множества не-медоидов.&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt;, соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; T),&amp;lt;/math&amp;gt; принимая все целочисленные значения, где:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;T\in \N&amp;lt;/math&amp;gt; - количество выполнений фазы SWAP во время работы алгоритма PAM.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* результат срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;O_{It-1}&amp;lt;/math&amp;gt; - множество не-медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It &amp;lt; T &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;третьей&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{a}=\overline{a}_{x_{m_i} } = \{ \min_{ x_{m_l} \in M  \backslash \{x_{m_i}\} }  \rho ( x_{m_l},x_j ) \| 1 \leq j \leq n \}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументом операции является &amp;lt;math&amp;gt;\overline{x}_{m_i}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;четвертой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{b}=\overline{b}_{x_{m_i} x_{o_p} } =  \{ \min (\overline{a}_{ x_{m_i}}^{(j)}, \rho ( x_{o_p},x_j )) \| 1 \leq j \leq n \}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_p}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{a}_{x_{m_i}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из третьей группы с координатами &amp;lt;math&amp;gt;It, i.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция S, соответствующая &#039;&#039;&#039;пятой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline {b}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{b}_{x_{m_i} x_{o_p} }&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из четвертой группы с координатами &amp;lt;math&amp;gt;It, i, p.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M1, соответствующая &#039;&#039;&#039;шестой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M1 = (F_{x_{o_p}}^{It}; x_{o_p}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt; \begin{cases}&lt;br /&gt;
F_{x_{o_p}}^{It} = \min_{x_{o_p} \in O} S &amp;amp; \quad\\&lt;br /&gt;
x_{o_p} = \arg F_{x_{o_p}}^{It} &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из пятой группы с первыми двумя координатами &amp;lt;math&amp;gt;It, i,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;n-k&amp;lt;/math&amp;gt; величин.&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M2, соответствующая &#039;&#039;&#039;седьмой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M2 = (F_{x_{o_p}, x_{m_i}}^{It}; x_{m_i}; x_{o_p}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;\begin{cases}&lt;br /&gt;
F_{x_{o_p}, x_{m_i}}^{It} = \min (\min_{x_{m_i} \in M} (F_{x_{o_p}}^{It}), M2_{It-1}) &amp;amp; \quad\\&lt;br /&gt;
x_{m_i} = \arg \min_{x_{m_i} \in M} M1 &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M1 = (F_{x_{o_p}}^{It}; x_{o_p})&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из шестой группы с координатами &amp;lt;math&amp;gt;It, i,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; величин;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M2_{It-1}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результаты срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; T&amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = T&amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описанный граф в общем случае представлен на Рис.3, отображена одна итерация фазы SWAP.&lt;br /&gt;
Обозначения:&lt;br /&gt;
# вершины первой группы обозначены фиолетовым цветом и подписаны как &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины второй группы обозначены синим цветом и подписаны как &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины третьей группы обозначены желтым цветом и подписаны как &amp;lt;math&amp;gt;\overline{a}_{x_{m_i} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины четвертой группы обозначены оранжевым цветом и подписаны как &amp;lt;math&amp;gt;\overline{b}_{x_{m_i o_p} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины пятой группы обозначены серым цветом и подписаны как &amp;lt;math&amp;gt;S;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины шестой группы обозначены зеленым цветом и подписаны как &amp;lt;math&amp;gt;M1;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины седьмой группы обозначены красным цветом и подписаны как &amp;lt;math&amp;gt;M2;&amp;lt;/math&amp;gt;&lt;br /&gt;
# синим дугам сопоставлены метки, отражающие данные, используемые в соответствующих оранжевых вершинах;&lt;br /&gt;
# фиолетовым дугам сопоставлены метки, отражающие данные, используемые в соответствующих жёлтых вершинах.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Pam swap 1.png|thumb|center|1100px|Рисунок 3. Граф фазы SWAP алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На Рис.4 представлен граф фазы SWAP для случая &amp;lt;math&amp;gt;n=6, k=2, T=3.&amp;lt;/math&amp;gt; Вершины, соответствующие операциям, получающим входные данные и производящим выходные данные, увеличены и выделены толстыми границами.&lt;br /&gt;
&lt;br /&gt;
[[file:Pam swap 2.png|thumb|center|1100px|Рисунок 4. Граф фазы SWAP алгоритма для n = 6, k = 2, T = 3.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
При параллельной реализации алгоритма PAM будем рассматривать параллельные варианты фазы BUILD и SWAP ([[#Возможная параллельная реализация алгоритма PAM|возможная параллельная реализация]]). Покажем, что сложность фазы BUILD сопоставима со сложностью одной итерации фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
Оценки последовательной сложности фаз BUILD и SWAP приведены в параграфе &amp;quot;[[#Последовательная сложность алгоритма|Последовательная сложность алгоритма]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Ресурс параллелизма фазы BUILD ====&lt;br /&gt;
&lt;br /&gt;
Для решения задачи кластеризации методом PAM в параллельном варианте фазы BUILD в предположении доступности неограниченного числа процессов для одной итерации необходимо выполнить:&lt;br /&gt;
*  1 ярус с нахождением &amp;lt;math&amp;gt;\overline{c}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* 1 ярус с нахождением суммы &amp;lt;math&amp;gt;S:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операцию сложения;&lt;br /&gt;
* 1 ярус с нахождением значений элемента &amp;lt;math&amp;gt;M1:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &amp;lt;math&amp;gt;\overline{MIN}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It&amp;gt;1;&amp;lt;/math&amp;gt;&lt;br /&gt;
* 1 ярус с изменением множеств медоидов и не-медоидов (не выполняются операции рассматриваемых типов).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность одного шага фазы BUILD равна: &lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операция сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It=1;&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It&amp;gt;1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность фазы BUILD при числе кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; равна: &lt;br /&gt;
* &amp;lt;math&amp;gt;kn-k&amp;lt;/math&amp;gt; операция сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;3kn - 2n - \frac{1}{2}k^2 - \frac{1}{2}k&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, по сравнению с последовательным, при &amp;lt;math&amp;gt;k, n \to \infty&amp;lt;/math&amp;gt; количество операций на один порядок меньше по параметру &amp;lt;math&amp;gt;n:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt; против &amp;lt;math&amp;gt;O(kn^2).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соотношение количества сложений и взятий минимума для фазы BUILD является постоянным и стремится к &amp;lt;math&amp;gt;3,&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;k, n \to \infty.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Максимальная ширина яруса достигается при вычислении &amp;lt;math&amp;gt;\overline {c}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; и равна &amp;lt;math&amp;gt;n-It+1&amp;lt;/math&amp;gt; для шага &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; фазы BUILD. Максимальная ширина яруса при рассмотрении всей фазы есть &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и достигается на первом шаге.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Ресурс параллелизма фазы SWAP ====&lt;br /&gt;
&lt;br /&gt;
Для решения задачи кластеризации методом PAM в параллельном варианте фазы SWAP в предположении доступности неограниченного числа процессов для одной итерации необходимо выполнить:&lt;br /&gt;
* 1 ярус с нахождением &amp;lt;math&amp;gt;\overline {a}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n(k-1)&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением &amp;lt;math&amp;gt;\overline {b}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением суммы &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;:&lt;br /&gt;
** &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операцию сложения;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &#039;первого&#039; вида &amp;lt;math&amp;gt;(M1 = \min_{x_{o_p} \in O} S):&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-k-1&amp;lt;/math&amp;gt; операцию нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &#039;второго&#039; вида &amp;lt;math&amp;gt;(M2 = \min_{x_{m_i} \in M} M1):&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt; операцию нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с изменением множеств медоидов и не-медоидов (не выполняются операции рассматриваемых типов).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность одной итерации фазы SWAP равна:&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - по количеству операций сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;kn + n - 2&amp;lt;/math&amp;gt; - по количеству операций нахождений минимума для двух чисел.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, по сравнению с последовательным, при &amp;lt;math&amp;gt;k, n \to \infty&amp;lt;/math&amp;gt; количество операций на один порядок меньше по параметру &amp;lt;math&amp;gt;n:&amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt; против &amp;lt;math&amp;gt;O(kn^2).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соотношение количества сложений и взятий минимума для одной итерации фазы SWAP является постоянным и равным &amp;lt;math&amp;gt;k,&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;n \to \infty&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Максимальная ширина яруса достигается при вычислении &amp;lt;math&amp;gt;\overline {b}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; и равна &amp;lt;math&amp;gt;k(n-k).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При использовании выбранной модели, в предположении доступности неограниченного числа вычислителей, фаза BUILD при &amp;lt;math&amp;gt;n \to \infty&amp;lt;/math&amp;gt; требует большего количества операций суммирования на порядок &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, по сравнению с одной итерацией фазы SWAP. В свою очередь, количество операций подсчёта минимума ассимптотически эквивалентны.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные&#039;&#039;:&lt;br /&gt;
* число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество точек упорядоченного множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
* число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество требуемых кластеров;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов, состоящих из &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; вещественных чисел, - попарных расстояний между элементами из множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; за исключением расстояний вида &amp;lt;math&amp;gt;\rho (x, x)=0, x \in X;&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;Объём входных данных&#039;&#039;: &amp;lt;math&amp;gt;n(n-1)&amp;lt;/math&amp;gt; вещественное число и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; целых числа.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Структура хранения данных&#039;&#039;:&lt;br /&gt;
* сразу после считывания входных данных составляется квадратная симметрическая матрица &amp;lt;math&amp;gt;D^{n * n}&amp;lt;/math&amp;gt;, у которой каждый элемент &amp;lt;math&amp;gt;d_{ij}&amp;lt;/math&amp;gt; является вещественным числом - расстоянием &amp;lt;math&amp;gt;\rho (x_i, x_j);&amp;lt;/math&amp;gt;&lt;br /&gt;
* для множества медоидов &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; создаётся массив из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; целых чисел - индексов принадлежащих ему элементов из множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, аналогичный массив &amp;lt;math&amp;gt;n-k&amp;lt;/math&amp;gt; целых чисел создаётся для множества не-медоидов &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
* для пересылки данных, как правило, используется тройка &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}; x_{m_s}; x_{o_h})&amp;lt;/math&amp;gt; или пара &amp;lt;math&amp;gt;(F_{x_{o_h}}^{i_j}; x_{o_h}),&amp;lt;/math&amp;gt; где:&lt;br /&gt;
** &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; - целое число, обозначающее порядковый номер элемента множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; - целое число, обозначающее порядковый номер элемента множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;F_{x_{m_s}, x_{o_h}}^{i_j}&amp;lt;/math&amp;gt; - вещественное число, равное минимальному значению целевой функции, вычисленному в текущем контексте.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Выходные данные&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; целых чисел, составляющих множество &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; вещественное число, являющееся значением целевой функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Объём выходных данных&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;  целых чисел и &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;  вещественное.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности алгоритма является &#039;&#039;линейным&#039;&#039; и равным &amp;lt;math&amp;gt;n.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Вычислительная мощность&#039;&#039; последовательного алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, равна &amp;lt;math&amp;gt;O(T*k).&amp;lt;/math&amp;gt;&lt;br /&gt;
Вычислительная мощность параллельного алгоритма равна &amp;lt;math&amp;gt;O(T*\frac{k}{n}).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм PAM является &#039;&#039;менее чувствительным&#039;&#039; к выбросам данных, чем алгоритм k-средних. Это связано с использованием медоидов, менее подверженных влиянию таких данных.&amp;lt;ref&amp;gt; Егоров А. В., Куприянова Н. И. Особенности методов кластеризации данных // Известия Южного федерального университета. Технические науки. –2011. T. 124, № 11. –С. 174-177.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Фиксированный способ выбора начальных приближений позволяет говорить о воспроизводимости полученных результатов для последовательной реализации. Для параллельной работы алгоритма подобная воспроизводимость отсутствует, так как из-за &#039;&#039;недетерминированности&#039;&#039; выбора элементов, на которых достигается минимальное значение целевой функции для каждой итерации, итоговое множество медоидов и, следовательно, значение целевой функции может меняться.&lt;br /&gt;
&lt;br /&gt;
Алгоритм PAM &#039;&#039;конечен&#039;&#039;, так как:&lt;br /&gt;
* количество операций фазы BUILD конечно;&lt;br /&gt;
* значение целевой фукнции неотрицательно и на каждой итерации фазы SWAP строго уменьшается.&lt;br /&gt;
&lt;br /&gt;
Одно из преимуществ алгоритма PAM заключается в том, что он может работать с любой матрицей различий. В данном случае принципиальное отличие от матрицы расстояний заключается в том, что для матрицы различий может не выполняться неравенство треугольника, так как в основе её построения не обязательно используется метрика.&lt;br /&gt;
&lt;br /&gt;
Основные операция алгоритма PAM: сложение и нахождение минимума. Операция взятия минимума не подвержена процессу накопления ошибки. На каждой итерации алгоритма сложение производится над значениями, взятыми непосредственно из исходных данных. Таким образом, алгоритм PAM не накапливает ошибок в процессе своей работы и является &#039;&#039;устойчивым&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;math&amp;gt;k(n-k) \, \bmod \, p \neq 0&amp;lt;/math&amp;gt; отсутствует возможность равномерно распределить задачи рассчёта &amp;lt;math&amp;gt;\overline{b}&amp;lt;/math&amp;gt; между процессами. Кроме того, если &amp;lt;math&amp;gt;k \, \bmod \, p \neq 0&amp;lt;/math&amp;gt;, то после их распределения для некоторых процессов окажется необходимым вычислить несколько соседних значений &amp;lt;math&amp;gt;\overline{a}.&amp;lt;/math&amp;gt; Таким образом, &#039;&#039;равномерная&#039;&#039; загрузка процессов &#039;&#039;не всегда возможна&#039;&#039;. Помимо этого, агрегирование данных с целью вычисления глобального минимума приводит к простою незадействованных процессов.&lt;br /&gt;
&lt;br /&gt;
Как и большинство алгоритмов кластеризации, PAM может сходиться к некоторому &#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;
==== Возможная параллельная реализация алгоритма PAM ====&lt;br /&gt;
&lt;br /&gt;
Необходимость уменьшения времени решения задачи приводит к потребности в создании паралельной реализации алгоритма. В дальнейшем будем придерживаться следующих допущений:&lt;br /&gt;
* возможно использование &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов;&lt;br /&gt;
* не нарушая общности суждений, множества &amp;lt;math&amp;gt;M, O&amp;lt;/math&amp;gt; - упорядоченны.&lt;br /&gt;
&lt;br /&gt;
Приведённые далее возможные схемы для параллельных реализаций фазы BUILD и фазы SWAP основаны на максимально равномерном распределении задач между процессами.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Возможная параллельная реализация фазы BUILD =====&lt;br /&gt;
&lt;br /&gt;
Главная задача заключается в распараллеливании многочисленных вычислений целевой функции на каждой итерации фазы BUILD:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{o_h} \in O_{i-1}} F_{x_{o_h}}^i,&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;F_{x_{o_h}}^i = \sum_{j = 1}^{n} \overline{MIN}_{i, x_{o_h}}^{(j)},&amp;lt;/math&amp;gt; где&lt;br /&gt;
: &amp;lt;math&amp;gt;\overline{MIN}_{1, x_{o_h} \in O_0} = \{ \rho (x_{o_h}, x_j ) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{o_h} \in O_{i-1}} = \{ \min ( \overline{MIN}_{i-1, x_{m_{i-1}}}^{(j)}, \rho (x_{o_h}, x_j) ) \| 1 \leq j \leq n \}, \forall i: 1 &amp;lt; i \leq k.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Схема реализации&#039;&#039;: &amp;lt;br&amp;gt;(далее &amp;lt;math&amp;gt;0 &amp;lt; i \leq k &amp;lt;/math&amp;gt; - номер текущей итерации)&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## положим:&lt;br /&gt;
##: &amp;lt;math&amp;gt;pos = p-(n-i+1) \, \bmod \, p;&amp;lt;/math&amp;gt;&lt;br /&gt;
## на каждой итерации процессу необходимо вычислить &amp;lt;math&amp;gt;r_j&amp;lt;/math&amp;gt; значений целевой функции для соответствующих ему элементов &amp;lt;math&amp;gt;x_{o_h}, ..., x_{o_{h+(r_j-1)}}:&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt; r_j = \begin{cases}&lt;br /&gt;
    \lfloor \frac{n-i+1}{p} \rfloor , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    \lceil \frac{n-i+1}{p} \rceil , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;h = \begin{cases}&lt;br /&gt;
    r_j*j , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    (r_j-1)*pos + (j-pos)*r_j , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# каждому процессу с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## найти минимум среди значений целевой функции &amp;lt;math&amp;gt;F_{x_{o_h}}^i&amp;lt;/math&amp;gt; для каждого из значений параметра &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt; &lt;br /&gt;
##* в данном случае может быть использована оптимизация, описанная в [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]];&lt;br /&gt;
## для процессов с номером &amp;lt;math&amp;gt;j \neq 0&amp;lt;/math&amp;gt; переслать процессу с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt; пару &amp;lt;math&amp;gt;(x_{o_h}, F_{x_{o_h}}^i)&amp;lt;/math&amp;gt; для всех обработанных &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# для процесса с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;:&lt;br /&gt;
## принять пары от процессов &amp;lt;math&amp;gt;(0, p-1],&amp;lt;/math&amp;gt; в ответ на шаг 2.2;&lt;br /&gt;
## найти &amp;lt;math&amp;gt;x_{o_h},&amp;lt;/math&amp;gt; для которого целевая функция принимает минимальное значение, и положить &amp;lt;math&amp;gt;x_{m_i}:=x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
## вычислить &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{m_i}}&amp;lt;/math&amp;gt;;&lt;br /&gt;
## разослать пару &amp;lt;math&amp;gt;(x_{m_i}, \overline{MIN}_{i, x_{m_i}})&amp;lt;/math&amp;gt; при помощи широковещательной рассылки;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять пару &amp;lt;math&amp;gt;(x_{m_i}, \overline{MIN}_{i, x_{m_i}})&amp;lt;/math&amp;gt; в ответ на шаг 3.4;&lt;br /&gt;
## скорректировать локальные копии множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt;, изменив принадлежность вектора &amp;lt;math&amp;gt;x_{m_i}&amp;lt;/math&amp;gt;, а также обновить хранимое значение вектора &amp;lt;math&amp;gt;\overline{MIN}&amp;lt;/math&amp;gt; для подготовки к следующей итерации;&lt;br /&gt;
## перейти к шагу 2.1.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
После завершения &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; шагов фазы BUILD, множества &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt; (одинаковые для каждого процесса согласно приведенной схеме), а так же значение целевой функции являются выходными данными фазы BUILD.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Возможная параллельная реализация фазы SWAP =====&lt;br /&gt;
&lt;br /&gt;
Главная задача заключается в распараллеливании многократного вычисления целевой функции на каждой итерации фазы SWAP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} } \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Схема реализации&#039;&#039;: &amp;lt;br&amp;gt;(далее &amp;lt;math&amp;gt;i \in \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;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## положим:&lt;br /&gt;
##: &amp;lt;math&amp;gt;pos = p-(k*(n-k)) \, \bmod \, p;&amp;lt;/math&amp;gt;&lt;br /&gt;
## на каждой итерации процессу необходимо вычислить &amp;lt;math&amp;gt;r_j&amp;lt;/math&amp;gt; значений целевой функции для соответствующих ему пар вида (медоид, не-медоид)   &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h}), (x_{m_s}, x_{o_{h+1}}), ..., (x_{m_s}, x_{o_{n-k}}), (x_{m_{s+1}}, x_{o_0}), (x_{m_{s+1}}, x_{o_1}), . . . \, : &amp;lt;/math&amp;gt;&lt;br /&gt;
##:&amp;lt;math&amp;gt; r_j =   \begin{cases}&lt;br /&gt;
    \lfloor \frac{k*(n-k)}{p} \rfloor , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    \lceil \frac{k*(n-k)}{p} \rceil , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;s = \begin{cases}&lt;br /&gt;
    (r_j*j) \mbox{ div } (n-k) , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
     ((r_j-1)*pos + r_j*(j-pos)) \mbox{ div } (n-k), pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{m_s};&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;h = \begin{cases}&lt;br /&gt;
    (r_j*j) \, \bmod \,  (n-k) , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
     ((r_j-1)*pos + r_j*(j-pos)) \, \bmod \,  (n-k), pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# каждому процессу с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## найти минимум среди вычисленных значений целевой функции для каждого из значений первого параметра &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; по соответствующим ему &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
##* в данном случае может быть использована оптимизация, описанная в [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]];&lt;br /&gt;
## переслать процессу с номером &amp;lt;math&amp;gt;N = s \, \bmod \, p&amp;lt;/math&amp;gt; (если &amp;lt;math&amp;gt;N \neq j&amp;lt;/math&amp;gt;) тройку &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}, x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; для всех обработанных &amp;lt;math&amp;gt;x_{m_s};&amp;lt;/math&amp;gt;&lt;br /&gt;
# для процессов с номерами &amp;lt;math&amp;gt;j&amp;lt;\min (p, k):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять описанные выше тройки от процессов, обработавших элементы &amp;lt;math&amp;gt;x_{m_{z \, \bmod \, p = j}}, z = \overline {0, k-1},&amp;lt;/math&amp;gt; в ответ на шаг 2.2;&lt;br /&gt;
## вычислить минимальное среди полученных значений целевой функции;&lt;br /&gt;
## запомнить &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, на которых минимальное значение было достигнуто;&lt;br /&gt;
## при &amp;lt;math&amp;gt;j \neq 0 &amp;lt;/math&amp;gt; отправить тройку &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}, x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, соответствующую выбранной паре, процессу с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
# для процесса с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;:&lt;br /&gt;
## принять тройки от процессов &amp;lt;math&amp;gt;(0, min(k-1, p-1)],&amp;lt;/math&amp;gt; в ответ на шаг 3.4;&lt;br /&gt;
## найти пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, для которой целевая функция принимает минимальное значение;&lt;br /&gt;
## сравнить найденное минимальное значение с вычисленным значением целевой функции на предыдущей итерации фазы SWAP;&lt;br /&gt;
### (&#039;&#039; &#039;&#039;&#039;условие останова&#039;&#039;&#039; &#039;&#039;) если значение целевой функции не уменьшилось, остановить вычисление;&lt;br /&gt;
### иначе, разослать выявленную пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; при помощи широковещательной рассылки;&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; в ответ на шаг 4.3.2;&lt;br /&gt;
## скорректировать локальные копии множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt;, заменяя элемент &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; на элемент &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; и наоборот;&lt;br /&gt;
## перейти к шагу 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Ограничения и недостатки =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Ограничения&#039;&#039;:&lt;br /&gt;
* предполагается, что матрица расстояний &amp;lt;math&amp;gt;D^{n * n}&amp;lt;/math&amp;gt; полностью помещается в памяти каждого процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Недостатки&#039;&#039;:&lt;br /&gt;
* при распределении обсчитываемых целевых функций, каждому из процессов ставится в соответствие некоторая совокупность пар &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, для которых нужно рассчитать значения целевой функции. В случае, если количество процессов не кратно количеству обрабатываемых кластеров, различные процессы получат пары у которых совпадают &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt;, что приведёт к совершению одинаковых вычислений на различных процессах: &amp;lt;math&amp;gt;   \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )), 1 \leq j \leq n;&amp;lt;/math&amp;gt;&lt;br /&gt;
* вычисление фазы SWAP успешно распараллеливается между &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессами, однако после этого происходит агрегация данных в 2 этапа относительно &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; для вычисления глобального минимума. На первом этапе данные собираются на первых &amp;lt;math&amp;gt;\min (p,k)&amp;lt;/math&amp;gt; процессах, где происходят локальные вычисления минимумов среди принятых данных (для каждого &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt;), после чего полученные минимумы и связанная с ними информация агрегируются на мастер-процессе, который вычисляет глобальный минимум и извещает о нём все остальные процессы. &amp;lt;br&amp;gt;Во время описанных вычислений все незадействованные процессы простаивают.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Дополнительные возможности&#039;&#039;:&lt;br /&gt;
* помимо описанной схемы, также есть возможность распараллелить операцию вычисления матрицы расстояний &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, однако это является отдельной алгоритмической задачей и не даёт существенного прироста производительности алгоритма.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Существующие параллельные реализации алгоритма PAM ====&lt;br /&gt;
&lt;br /&gt;
Примером другой параллельной реализации алгоритма PAM может служить реализация в пакете SPRINT для языка R (подробнее см. [[#Существующие реализации алгоритма|существующие реализации алгоритма]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Структура графа алгоритма (см. 1.7 [[#Информационный граф| Информационный граф алгоритма]]) такова, что позволяет надеяться на получение хорошей масштабируемости.&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма Partitioning Around Medoids проводилось на суперкомпьютере BlueGene/P &amp;lt;ref&amp;gt;IBM BlueGene/P  - [http://hpc.cmc.msu.ru http://hpc.cmc.msu.ru]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Отметим, что для данному суперкомпьютеру свойственна стабильность по времени вычисления одной и той же задачи при различных запусках.&lt;br /&gt;
Во время вычислений каждому MPI процессу соответствовало 1 ядро процессора PowerPC 450, 850 MHz с пиковой производительностью 3.4 GFlop/sec per core.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
* число процессов (p):&lt;br /&gt;
** [1; 4 : 512] с шагом 4 процесса;&lt;br /&gt;
* размер кластеризуемого множества (n):&lt;br /&gt;
** [4; 16; 32; 64];&lt;br /&gt;
** [128 : 3200] с шагом 128 элементов;&lt;br /&gt;
* каждому размеру кластеризуемого множества соответствует количество кластеров для разбиения (k):&lt;br /&gt;
** [2; 4; 4; 8];&lt;br /&gt;
** [2 : 50] с шагом 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Особенности проведения эксперимента:&lt;br /&gt;
* тестовые данные являются псевдослучайными;&lt;br /&gt;
* для всех экспериментов использовался одинаковый набор данных;&lt;br /&gt;
* в соответствии с описанными параметрами запуска, для множеств размерности [128 : 3200], количество кластеров (k) прямо пропорционально размеру задачи (n).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен широкий диапазон [[Глоссарий#Эффективность распараллеливания|эффективности реализации]] алгоритма:&lt;br /&gt;
* минимальная эффективность реализации: &amp;lt;math&amp;gt;3.4 * 10^{-9} \, %&amp;lt;/math&amp;gt; достигается при использовании 512 процессов для множества из 4 элементов и 2-х кластеров (результат вызван избыточностью количества процессов по отношению к размеру задачи);&lt;br /&gt;
* максимальная эффективность реализации: &amp;lt;math&amp;gt;4.1 * 10^{-4} \, %&amp;lt;/math&amp;gt; достигается при использовании 4 процессов для множества из 128 элементов и 2 кластеров.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Абсолютная величина [[Глоссарий#Производительность|производительности алгоритма]] (GFlops) определялась как количество операций с плавающей точкой за секунду. Точное количество операций было вычислено на основании [[#Последовательная сложность алгоритма| последовательной сложности алгоритма]], целочисленные операции и операции работы с памятью не учитывались.&lt;br /&gt;
&lt;br /&gt;
Таким образом, производительность обусловлена как самим алгоритмом (его внутренняя структура определяет соотношение между операциями работы с памятью, операциями над целочисленными значениями и значениями с плавающей точкой), так и используемой реализацией.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации PAM в зависимости от изменяемых параметров запуска:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;margin: 0 auto;&amp;quot;&lt;br /&gt;
 | [[file:PAM-gflops.png|thumb|none|600px|Рисунок 5а. Параллельная реализация алгоритма PAM. Изменение производительности в зависимости от числа процессов и размера множества.]]&lt;br /&gt;
 | [[file:PAM-gflops-top-view.png|thumb|none|600px|Рисунок 5б. Параллельная реализация алгоритма PAM. Изменение производительности в зависимости от числа процессов и размера множества. Вид сверху.]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
[[file:PAM-gflops.png|thumb|center|800px|Рисунок 5а. Параллельная реализация алгоритма PAM. Изменение производительности в зависимости от числа процессов и размера множества.]]&lt;br /&gt;
[[file:PAM-gflops-top-view.png|thumb|center|800px|Рисунок 5б. Параллельная реализация алгоритма PAM. Изменение производительности в зависимости от числа процессов и размера множества. Вид сверху.]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
[[file:PAM-efficiency.png|thumb|center|800px|Рисунок 6. Параллельная реализация алгоритма PAM. Изменение эффективности в зависимости от числа процессов и размера множества.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рисунке 5б, видно, что пики организованы в прямые. Это обусловлено инвариантностью величины &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; в соответствии с описанной в [[#Вычислительное ядро алгоритма | вычислительном ядре фазы SWAP]] оптимизацией. На рисунке 3 для [[#Информационный граф фазы SWAP| информационного графа фазы SWAP]] наглядно видно, что при построчном распределении вычислений &amp;lt;math&amp;gt;\overline{b}_{x_{m_s, o_h}}&amp;lt;/math&amp;gt; возможно возникновение следующих ситуаций (далее при &#039;&#039; &#039;&#039;&#039;k * (n-k) mod p == 0&#039;&#039;&#039; &#039;&#039; обозначим &#039;&#039; &#039;&#039;&#039;r = k * (n-k) / p&#039;&#039;&#039; &#039;&#039;):&lt;br /&gt;
# при &#039;&#039; &#039;&#039;&#039;r &amp;lt; (n-k)&#039;&#039;&#039; &#039;&#039;, если &#039;&#039; &#039;&#039;&#039;(n-k) mod r == 0&#039;&#039;&#039; &#039;&#039;, то каждому процессу необходимо вычислить ровно одну величину &amp;lt;math&amp;gt;\overline{a}_{x_{m_s}};&amp;lt;/math&amp;gt;&lt;br /&gt;
# при &#039;&#039; &#039;&#039;&#039;r &amp;amp;ge; (n-k)&#039;&#039;&#039; &#039;&#039;, если &#039;&#039; &#039;&#039;&#039;k mod p == 0&#039;&#039;&#039; &#039;&#039;, то каждому процессу необходимо вычислить несколько соответствующих ему величин &amp;lt;math&amp;gt;\overline{a}_{x_{m_s}},&amp;lt;/math&amp;gt; при этом каждая величина будет вычислена ровно в одном процессе;&lt;br /&gt;
# в остальных случаях вычисления величин &amp;lt;math&amp;gt;\overline{b}_{x_{m_s, o_h}}&amp;lt;/math&amp;gt; распределяются между процессами таким образом, что часть процессов обрабатывает больше величин &amp;lt;math&amp;gt;\overline{a}_{x_{m_s}}&amp;lt;/math&amp;gt; нежели остальные (ситуация возникает при обработке процессом последних элементов одной строки и первых элементов следующей). Подобная ситуация приводит к дополнительным вычислениям на некоторых процессах и, как следствие, к простою остальных, в связи с чем происходит падение производительности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Первые два случая приводят к равномерному распределению нагрузки между процессами, и им соответствуют видимые пики на приведённых рисунках 5a, 5б, 6. Для 3-го случая из-за неравномерной загрузки процессов достигаемая производительность падает.&lt;br /&gt;
&lt;br /&gt;
Второй случай соответствует размеру задачи меньшему, чем количество процессов и на практике маловероятен.&lt;br /&gt;
Таким образом, для повышения производительности следует выбирать количество процессов так, чтобы &#039;&#039; &#039;&#039;&#039;k * (n-k)&#039;&#039;&#039; &#039;&#039; и &#039;&#039; &#039;&#039;&#039;(n-k)&#039;&#039;&#039; &#039;&#039; были кратны &#039;&#039; &#039;&#039;&#039;p&#039;&#039;&#039; &#039;&#039; и &#039;&#039; &#039;&#039;&#039;k * (n-k) div p&#039;&#039;&#039; &#039;&#039; соответственно.&lt;br /&gt;
&lt;br /&gt;
Для исследуемой реализации, вычисление величин &amp;lt;math&amp;gt;\overline{a}_{x_{m_s}}&amp;lt;/math&amp;gt; может быть оптимизировано (за счёт распределения между процессами и последующих пересылок). Однако принципиальный вид графиков останется тем же: пики будут наблюдаться для случаев равномерного распределения вычислительных задач между процессами.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости выбранной реализации алгоритма PAM:&lt;br /&gt;
* По числу процессов: &amp;lt;math&amp;gt;- \, 1.6 * 10^{-8}.&amp;lt;/math&amp;gt; С ростом числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается. Этот результат вызван ростом времени, затрачиваемого на пересылку данных, то есть ростом накладных расходов на организацию параллельного выполнения.&lt;br /&gt;
* По размеру задачи: &amp;lt;math&amp;gt;3.9 * 10^{-7}&amp;lt;/math&amp;gt;. С ростом размера задачи эффективность на рассмотренной области изменений параметров запуска увеличивается. Этот результат вызван увеличением количества вычислений относительно объема пересылок данных.&lt;br /&gt;
* Общая оценка масштабируемости: &amp;lt;math&amp;gt;- \, 1.2 * 10^{-9}&amp;lt;/math&amp;gt;. При рассмотрении области параметров запуска в целом можно говорить о том, что с ростом размера задачи и числа процессов эффективность незначительно падает.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/phonexicum/pam-mpi-cmc Исследованная параллельная реализация на языке C++] (реализация написана самостоятельно)&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# Последовательная реализация алгоритма PAM в пакете ClusterR на языке R:&lt;br /&gt;
#* Лицензия: MIT&lt;br /&gt;
#* [https://cran.r-project.org/package=ClusterR веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в функции &#039;Cluster_Medoids&#039;. Отличительная особенность реализации &amp;lt;ref&amp;gt;Lampros Mouselimis [https://cran.r-project.org/web/packages/cluster/cluster.pdf Package &#039;ClusterR&#039;]. October 8, 2016&amp;lt;/ref&amp;gt;:&lt;br /&gt;
#** для задания метрики между элементами кластеризуемого множества передаётся строка, задающая одну из реализованных в алгоритме метрик. Данный подход теряет одно из преимуществ алгоритма PAM, позволяющее в качестве матрицы расстояний использовать произвольную матрицу различий.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Последовательная реализация алгоритма PAM в пакете Cluster на языке R:&lt;br /&gt;
#* Лицензия: GPL (≥2)&lt;br /&gt;
#* [https://cran.r-project.org/package=cluster веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в функции &#039;pam()&#039;. Данная реализация имеет следующие особенности &amp;lt;ref&amp;gt;Martin Maechler., etc. [https://cran.r-project.org/web/packages/cluster/cluster.pdf Package &#039;cluster&#039;]. October 8, 2016&amp;lt;/ref&amp;gt;:&lt;br /&gt;
#** функция может принимать на вход не множество точек, а матрицу расстояний между ними;&lt;br /&gt;
#** реализация более гибкая, так как принимает на вход матрицу различий элементов, а не использует какую-либо метрику;&lt;br /&gt;
#** может быть предоставлено графическое отображение.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Параллельная реализация алгоритма PAM в пакете SPRINT (Simple Parallel R INTerface - параллельный фреймворк) на языке R:&lt;br /&gt;
#* Лицензия: GPL (≥3)&lt;br /&gt;
#* [https://cran.r-project.org/package=sprint веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в фукции &#039;ppam()&#039;. Входные параметры данной функции схожи с параметрами, задаваемыми в линейной реализации &#039;pam()&#039; пакета Cluster языка R. Отличительной особенностью является подача на вход предвычисленной матрицы расстояний (например, с помощью функции &#039;pcor()&#039; из этой же библиотеки).&amp;lt;ref&amp;gt;University of Edinburgh SPRINT Team. [https://cran.r-project.org/web/packages/sprint/sprint.pdf Package &#039;sprint&#039;]. February 20, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Параллельная реализация алгоритма PAM на основе операций MapReduce на Hadoop кластере.&lt;br /&gt;
#* В рамках исследования по ускорению анализа информации о геноме были созданы реализации алгоритма PAM с использованием технологии MPI и технологии MapReduce. Реализация в открытом досупе отсутствует. &amp;lt;ref&amp;gt;Dobrzelecki B. et al. Managing and analysing Genomic Data using HPC and Clouds //Grid and Cloud Database Management. – Springer Berlin Heidelberg, 2011. – С. 261-277.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
MKL, ScaLAPACK, PETSc, FFTW, ATLAS, Magma и другие подобные библиотеки.&lt;br /&gt;
&lt;br /&gt;
* Дать ссылки на существующие последовательные и параллельные реализации алгоритма (&amp;quot;уже доступные&amp;quot;)&lt;br /&gt;
* Реализация - коммерческая/свободная, лицензия&lt;br /&gt;
* ссылка на дистрибутив и описание&lt;br /&gt;
* особенности, достоинства/недостатки, ....&lt;br /&gt;
&lt;br /&gt;
гугл-запрос: &amp;quot;partitioning around medoids&amp;quot; &amp;quot;PAM&amp;quot; BUILD SWAP &amp;quot;MPI&amp;quot; &amp;quot;program&amp;quot; &amp;quot;package&amp;quot; -worldwidescience&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Anastasia</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:Avasilenko/Partitioning_Around_Medoids_(PAM)&amp;diff=16251</id>
		<title>Участник:Avasilenko/Partitioning Around Medoids (PAM)</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:Avasilenko/Partitioning_Around_Medoids_(PAM)&amp;diff=16251"/>
		<updated>2016-11-09T11:54:46Z</updated>

		<summary type="html">&lt;p&gt;Anastasia: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Partitioning Around Medoids&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(T*kn^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*(n-1)+2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;k+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(T*kn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(k(n-k))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Авторы&#039;&#039;&#039;:&lt;br /&gt;
* [[Участник:Avasilenko|А.Э.Василенко]] (отвечает за программистскую составляющую);&lt;br /&gt;
* [[Участник:Anastasia|А.В.Тузикова]] (отвечает за математическую составляющую).&lt;br /&gt;
Вклад авторов считать равноценным, чётких границ ответственности провести невозможно.&lt;br /&gt;
&lt;br /&gt;
==Свойства и структура алгоритма==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
 &lt;br /&gt;
Объединение схожих объектов в группы - один из важнейших видов человеческой деятельности&amp;lt;ref&amp;gt;Rousseeuw P. J., Kaufman L. Finding Groups in Data. – Wiley Online Library, 1990.&amp;lt;/ref&amp;gt;. Более того - это важная часть процесса познания мира, в котором мы живем. Мы учим детей различать кошек и собак, воду и песок, мужчин и женщин путем постоянного развития и улучшения подсознательных схем классификации. Примеры есть и во взрослой жизни – в химии необходимо классифицировать соединения, в археологии – объединять находки по периодам и т.д.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задача кластеризации&#039;&#039;&#039; - разделение множества объектов на заданное число множеств с минимизацией некоторого функционала - является популярной задачей, относится к разделу машинного обучения и находит применение в таких областях, как анализ текста, биоинформатика, интеллектуальные транспортные системы и др. &amp;lt;ref&amp;gt; Речкалов Т.В. Параллельный алгоритм кластеризации для многоядерного сопроцессора Intel Xeon Phi // Суперкомпьютерные дни в России: Труды vеждународной конференции. – М.: Изд-во МГУ, 2015, c. 532.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существует несколько видов кластеризации&amp;lt;ref&amp;gt;Маннинг К.Д., Введение в информационный поиск: пер. с англ. / К.Д. Маннинг, П. Рагхаван, Х.Шютце - М. : Вильямс, 2011. - 528.&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;плоская кластеризация&#039;&#039; (&#039;&#039;flat clustering&#039;&#039;) - порождает совокупность кластеров, не имеющих явных взаимосвязей;&lt;br /&gt;
* &#039;&#039;иерархическая кластеризация&#039;&#039; (&#039;&#039;hierarchical clustering&#039;&#039;) - создаёт иерархию кластеров.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PAM&#039;&#039;&#039; (&#039;&#039;&#039;Partitioning Around Medoids&#039;&#039;&#039;) - плоский алгоритм кластеризации, позволяющий выделить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров (множеств), удовлетворяющих следующим свойствам:&lt;br /&gt;
 &lt;br /&gt;
*   каждая группа содержит хотя бы один объект;&lt;br /&gt;
*   каждый объект принадлежит ровно одной группе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Модель &amp;lt;ref&amp;gt;Kaufman, L. and Rousseeuw, P.J., Clustering by means of Medoids. In: Y. Dodge and North-Holland, editor. Statistical Data Analysis Based on the L1-Norm and Related Methods. Springer US; 1987, p. 405–416.&amp;lt;/ref&amp;gt;, лежащая в основе алгоритма PAM, основана на выборе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов, являющихся характерными точками соответствующего кластера. Таким образом, кластерам сопоставляются принадлежащие им объекты, называемые &#039;&#039;&#039;медоидами&#039;&#039;&#039;, на основании которых распределяются остальные объекты по принципу наибольшего сходства. Cама модель называется моделью &#039;&#039;&#039;k-medoids&#039;&#039;&#039; (не путать с моделью &#039;&#039;k-median&#039;&#039;).&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
PAM состоит из двух фаз: &#039;&#039;&#039;BUILD&#039;&#039;&#039; и &#039;&#039;&#039;SWAP&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
*   на фазе BUILD выполняется первичная кластеризация, в ходе которой последовательно выбираются &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов в качестве медоидов;&lt;br /&gt;
*   фаза SWAP представляет собой итерационный процесс, в ходе которого производятся попытки улучшить множество медоидов. Алгоритм выполняет поиск пары объектов (медоид, не-медоид), минимизирующих целевую функцию при замене, после чего обновляет множество медоидов.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации алгоритма выбирается пара (медоид, не-медоид) такая, что замена медоида &amp;lt;math&amp;gt;x_{m_l}&amp;lt;/math&amp;gt; на не-медоид &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; дает лучшую кластеризацию из возможных. Оценка кластеризации выполняется с помощью целевой функции, вычисляемой как сумма расстояний от каждого объекта до ближайшего медоида:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum_{j = 1}^n \min_{1 \leq l \leq k} \rho ( x_{m_l},x_{o_h} )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура изменения множества медоидов повторяется, пока есть возможность улучшения значения целевой функции.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Исходные данные&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
*   множество кластеризуемых объектов &amp;lt;math&amp;gt;X = \{ x_1, x_2, ... , x_n \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; - кортеж, состоящий из &amp;lt;math&amp;gt; w &amp;lt;/math&amp;gt; вещественных чисел;&lt;br /&gt;
*   симметрическая матрица &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, элементы матрицы &amp;lt;math&amp;gt;d_{ij}=d(i,j)&amp;lt;/math&amp;gt; - вычисленные расстояния между объектами &amp;lt;math&amp;gt;x_i, x_j&amp;lt;/math&amp;gt;;&lt;br /&gt;
*   количество кластеров &amp;lt;math&amp;gt;k \leq n.&amp;lt;/math&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Обозначения&#039;&#039;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;M = \{ x_{m_1}, x_{m_2}, ... , x_{m_k} \} &amp;lt;/math&amp;gt; - множество медоидов, &amp;lt;math&amp;gt; M \subseteq X ;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;O = \{ x_{o_1}, x_{o_2}, ... , x_{o_r} \} &amp;lt;/math&amp;gt; - множество не-медоидов, &amp;lt;math&amp;gt; O \subseteq X, &amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;r=n-k;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;d_{ij}=\rho (x_i, x_j )&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \rho  : X \times X \rightarrow R &amp;lt;/math&amp;gt; — метрика расстояния;&lt;br /&gt;
*   &amp;lt;math&amp;gt;F_{M,O} = \sum_{j = 1}^{n} \min_{ x_{m_l} \in M} \rho ( x_{m_l},x_{o_j} )&amp;lt;/math&amp;gt; - значение целевой функции для заданных множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;T^i&amp;lt;/math&amp;gt; - изменение целевой функции на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-м шаге фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Выходные данные&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;M = \{ x_{m_1}, x_{m_2}, ... , x_{m_k} \}&amp;lt;/math&amp;gt; - множество медоидов;&lt;br /&gt;
* &amp;lt;math&amp;gt;K_{m_i} = \{ x_{o_h} \in O \| x_{m_i} = \arg \min_{x_{m_s} \in M} \rho (x_{o_h}, x_{m_s}) \}, 1 \leq i \leq k&amp;lt;/math&amp;gt; - искомые кластеры.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Вычислительные формулы метода&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
*   &#039;&#039;фаза BUILD&#039;&#039; (состоит из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; шагов последовательного выбора &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; медоидов):&lt;br /&gt;
**   &amp;lt;math&amp;gt;O_0 = X, M_0 = \varnothing ;&amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_1} = \arg \min_{x_{o_h} \in O_0} \sum_{j = 1}^n \rho \left ( x_{o_h},x_j \right ), O_1 = O_0 \backslash \{x_{m_1}\}, M_1 = M_1 \cup \{x_{m_1}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_2} = \arg \min_{x_{o_h} \in O_1} \sum_{j = 1}^{n} \min ( \rho ( x_{m_1},x_j ), \rho ( x_{o_h},x_j ) ), O_2 = O_1 \backslash \{x_{m_2}\}, M_2 = M_1 \cup \{x_{m_2}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_3} = \arg \min_{x_{o_h} \in O_2} \sum_{j = 1}^{n} \min_{1 \leq l \leq 2} ( \rho ( x_{m_l},x_j ) , \rho ( x_{o_h},x_j ) ) , O_3 = O_2 \backslash \{x_{m_3}\}, M_3 = M_3 \cup \{x_{m_3}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
** ...&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_k} = \arg \min_{x_{o_h} \in O_{k-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{k-1}} ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j ) ) , O_k = O_{k-1} \backslash \{x_{m_k}\}, M_k = M_{k-1} \cup \{x_{m_k}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;фаза SWAP&#039;&#039; (итерационный процесс):&lt;br /&gt;
** начальное приближение: &amp;lt;math&amp;gt;O_0 = O_k^{BUILD}, M_0 = M_k^{BUILD};&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й шаг итерации:&lt;br /&gt;
*** вычисление целевой функции при оптимальной замене (замене, при которой достигается лучшая кластеризация из возможных на текущей итерации): &amp;lt;br&amp;gt;&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j) ); &amp;lt;/math&amp;gt;&lt;br /&gt;
*** определение пары (медоид, не-медоид), на которой достигается оптимальная замена: &amp;lt;br&amp;gt;&amp;lt;math&amp;gt; (x_{m_s}, x_{o_h}) = \arg F^i; &amp;lt;/math&amp;gt;&lt;br /&gt;
*** проверка критерия останова;&lt;br /&gt;
*** изменение множеств в соответствии с выбранной парой &amp;lt;math&amp;gt; (x_{m_s}, x_{o_h}):&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&amp;lt;math&amp;gt;M_i = M_{i-1} \backslash \{x_{m_s}\} \cup \{x_{o_h}\} , O_i = O_{i-1} \cup \{x_{m_s}\} \backslash \{x_{o_h}\} ;&amp;lt;/math&amp;gt;&lt;br /&gt;
** критерий останова:&lt;br /&gt;
*** &amp;lt;math&amp;gt;T^i = F^{i-1} - F^{i} \leq 0 .&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро алгоритма PAM на этапе BUILD&#039;&#039;&#039; состоит из многочисленных вычислений значений целевой функции при различных вариантах выбора дополнительного медоида (шаг алгоритма &amp;lt;math&amp;gt;1 \leq i \leq k&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1}} ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j ) ) = \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \overline{MIN}_{i, x_{o_h}}^{(j)},&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;\overline{MIN}_{1, x_{o_h} \in O_0} = \{ \rho (x_{o_h}, x_j ) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{o_h} \in O_{i-1}} = \{ \min ( \overline{MIN}_{i-1, x_{m_{i-1}}}^{(j)}, \rho (x_{o_h}, x_j) ) \| 1 \leq j \leq n \}, \forall i: 1 &amp;lt; i \leq k.&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;|O_{i-1}| = n-i+1&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Оптимизация&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* таким образом, на каждой последующей итерации можно использовать величину, вычисленную на предыдущем шаге, что позволяет сократить число вычислений минимумов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро алгоритма PAM на этапе SWAP&#039;&#039;&#039; состоит из многочисленных вычислений значений целевой функции при различных вариантах замены некоторого существующего медоида на элемент из числа не-медоидов. &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-я итерация фазы SWAP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j) ) =&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;= \min_{x_{m_s} \in M_{i-1} } \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Оптимизация&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* таким образом, при поиске пары (медоид, не-медоид), наилучшим образом минимизирующей целевую функцию, происходит поиск минимума по всем возможным элементам &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, для которых вычисляется &amp;lt;math&amp;gt;\sum_{j = 1}^{n} \min (a, b)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt; \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )),&amp;lt;/math&amp;gt; и является инвариантом по отношению к &amp;lt;math&amp;gt;\min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) ),&amp;lt;/math&amp;gt; что позволяет предвычислить элемент &amp;lt;math&amp;gt;a.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Опишем макрооперации алгоритма&#039;&#039;:&lt;br /&gt;
* в случае если алгоритму PAM на вход подаётся набор точек с их координатами в пространстве &amp;lt;math&amp;gt;R^w,&amp;lt;/math&amp;gt; то необходимо вычислить матрицу расстояний. Для этого может быть использована, например, евклидова метрика:&lt;br /&gt;
*: &amp;lt;math&amp;gt;\rho (p,q)=\sqrt{(p_1-q_1)^2+(p_2-q_2)^2+\dots+(p_w-q_w)^2} = \sqrt{\sum_{j=1}^w (p_j-q_j)^2} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p, q \in R^w;&amp;lt;/math&amp;gt;&lt;br /&gt;
* нахождение минимального среди значений, принимаемых некоторой функцией &amp;lt;math&amp;gt;value,&amp;lt;/math&amp;gt; определённой на дискретном множестве &amp;lt;math&amp;gt;Y=\{y_i\}, \, i = \overline{(1,r)}:&amp;lt;/math&amp;gt;&lt;br /&gt;
*: &amp;lt;math&amp;gt;minimum_{y \in Y } (value (y)) = \min \Bigg(value(y_1), \min \bigg(value(y_2), \min \Big(\dots , \min(value(y_{r-1}), value(y_{r})) ... \Big) \bigg)\Bigg);&amp;lt;/math&amp;gt;&lt;br /&gt;
* вычисление вектора инвариантов, используемых при оптимизации фазы SWAP (см. вычислительное ядро алгоритма):&lt;br /&gt;
*: &amp;lt;math&amp;gt;\overline{a} = \{ minimum_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l}, x_j ) ) \| 1 \leq j \leq n \},&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;i - &amp;lt;/math&amp;gt;номер итерации;&lt;br /&gt;
* вычисление вектора расстояний от каждой точки заданного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; до ближайшего медоида из множества &amp;lt;math&amp;gt;M_{i-1} \backslash \{x_{m_s}\},&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;i - &amp;lt;/math&amp;gt;номер итерации фазы SWAP: &lt;br /&gt;
*: &amp;lt;math&amp;gt;\overline{b} = \{ \min (\overline{a}^{(j)}, \rho ( x_{o_p}, x_j )) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
* сложение компонент вектора: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline{f}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Макроструктура вычислительного ядра алгоритма PAM&#039;&#039; может быть выражена через макрооперации следующим образом:&lt;br /&gt;
* для ядра фазы BUILD:&lt;br /&gt;
*::: &amp;lt;math&amp;gt;F^i = minimum_{ x_{o_h} \in O_{i-1} } ( S \, ( \overline{f} (x_{o_h}) )),&amp;lt;/math&amp;gt;&lt;br /&gt;
*::: &amp;lt;math&amp;gt;\overline{f} = \{ \min \,( \overline{MIN}_{i, x_{o_h}}^{(j)}, \rho (x_{o_h}, x_j)) \| 1 \leq j \leq n \}, &amp;lt;/math&amp;gt; где&lt;br /&gt;
*# &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;n-i+1&amp;lt;/math&amp;gt; раз;&lt;br /&gt;
*# &amp;lt;math&amp;gt;minimum&amp;lt;/math&amp;gt; находится &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; раз при вычислении наилучшего значения целевой функции на текущей итерации.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* для ядра фазы SWAP:&lt;br /&gt;
*::: &amp;lt;math&amp;gt;F^i = minimum_{ x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1} } ( S \, ( \overline{b} \, ( x_{o_h}, \overline{a} \, (x_{m_s}) ) )),&amp;lt;/math&amp;gt; где:&lt;br /&gt;
*# &amp;lt;math&amp;gt;minimum&amp;lt;/math&amp;gt; находится &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; раз  в процессе вычисления макрооперации &amp;lt;math&amp;gt;\overline {a};&amp;lt;/math&amp;gt;&lt;br /&gt;
*# &amp;lt;math&amp;gt;\overline {a}&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; раз и использует вычисленные на шаге 1 минимальные значения;&lt;br /&gt;
*# &amp;lt;math&amp;gt;\overline {b}&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;k(n-k)&amp;lt;/math&amp;gt; раз и использует вычисленные на шаге 2 значения &amp;lt;math&amp;gt;\overline {a};&amp;lt;/math&amp;gt;&lt;br /&gt;
*# &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; вычисляется &amp;lt;math&amp;gt;k(n-k)&amp;lt;/math&amp;gt; раз и использует вычисленные на шаге 3 значения &amp;lt;math&amp;gt;\overline {b};&amp;lt;/math&amp;gt;&lt;br /&gt;
*# &amp;lt;math&amp;gt;minimum&amp;lt;/math&amp;gt; находится &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; раз при вычислении наилучшего значения целевой функции на текущей итерации.&lt;br /&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;&#039;&#039;  : Множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; или матрица расстояний &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, количество кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;&lt;br /&gt;
 &#039;&#039;&#039;Выход&#039;&#039;&#039; : Множество медоидов &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
 0  Если на вход было подано множество объектов, необходимо предварительно вычислить матрицу расстояний;&lt;br /&gt;
 1  Инициализация множеств &amp;lt;math&amp;gt;M := \varnothing, O := X;&amp;lt;/math&amp;gt;&lt;br /&gt;
 &amp;amp;nbsp;&lt;br /&gt;
    // фаза BUILD&lt;br /&gt;
 2  &#039;&#039;&#039;for (int i := 1; i &amp;lt;= k; i++)&#039;&#039;&#039; {&lt;br /&gt;
        // Найти &amp;lt;math&amp;gt;x_{m_i}:&amp;lt;/math&amp;gt;&lt;br /&gt;
        {&lt;br /&gt;
 3          Для всех &amp;lt;math&amp;gt;x_{o_h} \in O&amp;lt;/math&amp;gt; вычислить &amp;lt;math&amp;gt;F_{M \cup \{x_{o_h}\}, O \backslash \{x_{o_h}\}};&amp;lt;/math&amp;gt;&lt;br /&gt;
 4          Положить &amp;lt;math&amp;gt;x_{m_i}&amp;lt;/math&amp;gt; равным &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, соответствующему минимальному из вычисленных &amp;lt;math&amp;gt;F;&amp;lt;/math&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
 5      Обновить множества &amp;lt;math&amp;gt;M := M \cup \{x_{m_i}\}, O := O \backslash \{x_{m_i}\};&amp;lt;/math&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
    // фаза SWAP&lt;br /&gt;
 6  &#039;&#039;&#039;while (1)&#039;&#039;&#039; {&lt;br /&gt;
        // Найти пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h}),&amp;lt;/math&amp;gt; на которой достигается оптимальная замена:&lt;br /&gt;
        {&lt;br /&gt;
 7          Для всех &amp;lt;math&amp;gt;x_{m_i} \in M, x_{o_j} \in O&amp;lt;/math&amp;gt; вычислить &amp;lt;math&amp;gt;F^i;&amp;lt;/math&amp;gt; // вычисление проводить с учётом приведённой ранее оптимизации (см. 1.3 [[#Вычислительное ядро алгоритма|Вычислительное ядро алгоритма]]);&lt;br /&gt;
 8          Положить пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; равной паре &amp;lt;math&amp;gt;(x_{m_i}, x_{o_j})&amp;lt;/math&amp;gt;, соответствующей минимальному из вычисленных &amp;lt;math&amp;gt;F;&amp;lt;/math&amp;gt;&lt;br /&gt;
        }&lt;br /&gt;
 9      Вычислить &amp;lt;math&amp;gt;T^i;&amp;lt;/math&amp;gt; // критерий останова (см. 1.2 [[#Математическое описание алгоритма|Математическое описание алгоритма]])&lt;br /&gt;
 10     &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;(T^i &amp;gt; 0)&amp;lt;/math&amp;gt; {&lt;br /&gt;
 11         Обновить множества &amp;lt;math&amp;gt;M := M \backslash \{x_{m_s}\} \cup \{x_{o_h}\}, O := O \cup \{x_{m_s}\} \backslash \{x_{o_h}\};&amp;lt;/math&amp;gt;&lt;br /&gt;
 12     } &#039;&#039;&#039;else&#039;&#039;&#039; {&lt;br /&gt;
 13         &#039;&#039;&#039;break&#039;&#039;&#039;;&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;&#039;&#039;. Необходимо предварительно вычислить матрицу расстояний и сохранить её в памяти, так как в ходе вычисления алгоритма многократно используются расстояния между элементами, а вычисление каждого из них является ресурсоёмкой операцией из нескольких умножений и одного извлечения квадратного корня.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Минимизация кеш-промахов&#039;&#039;&#039;. Матрица расстояний, к которой постоянно выполняется доступ на чтение для вычисления минимумов и их суммирования, должна храниться в памяти как матрица размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, несмотря на то, что она симметрическая и достаточно хранить лишь половину (элементы над или под главной диагональю). Данная оптимизация потребует использования в 2 раза большего количества памяти для хранения расстояний (а это является главным расходом памяти программы, так как все остальные используемые данные являются временными (локальными для каждой операции) и представляют из себя несколько векторов длинной &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов). Однако так как в данном алгоритме доступ к матрице осуществляется построчно (в  [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]] поэлементно ищутся  минимумы 2-х векторов, после чего все они складываются), то в этом случае из матрицы можно будет читать данные по строкам подряд, что снижает количество кеш-промахов. Использование только половины матрицы приводит к частым промахам в кеше в связи с необходимостью загрузки части векторов по строкам, а части - по столбцам.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления &#039;&#039;&#039;матрицы расстояний&#039;&#039;&#039; требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций вычисления расстояний;&lt;br /&gt;
* сложность каждой операции вычисления расстояния (для случая использования Евклидовой метрики) равна &amp;lt;math&amp;gt;2*w-1&amp;lt;/math&amp;gt; операций сложения и вычитания, &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; операций возведения в квадрат (умножения) и &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операции извлечения квадратного корня.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основании формулы из описания &#039;&#039;&#039;вычислительного ядра фазы BUILD&#039;&#039;&#039; определим сложность выполнения всего этапа.&lt;br /&gt;
&lt;br /&gt;
Обозначим:&lt;br /&gt;
*&amp;lt;math&amp;gt;summs&amp;lt;/math&amp;gt; - операция сложения двух вещественных чисел;&lt;br /&gt;
*&amp;lt;math&amp;gt;mins&amp;lt;/math&amp;gt; - операция нахождения минимума для двух вещественных чисел.&lt;br /&gt;
&lt;br /&gt;
Тогда, количество операций равно:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = ( ( (n-1) summs ) * (n-1+1) + (n-1+1-1)mins) + \sum_{i = 2}^{k} ( ( (1 mins)*(n-1) + (n-1) summs ) * (n-i+1) + (n-i+1-1)mins) \Rightarrow&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Rightarrow S =&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = ( ( 0 ) * (n-1+1) + (n-1+1-1)mins) + \sum_{i = 2}^{k} ( ( (1 mins)*(n-1)) * (n-i+1) + (n-i+1-1)mins ) &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = \sum_{i = 1}^{k} ( ( (n-1) summs ) * (n-i+1) ) &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
=&lt;br /&gt;
&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
=&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = n^2(k-1) - \frac{1}{2}(nk^2 - nk) + n - k &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = n^2k - \frac{1}{2}(nk^2 + nk - k^2 + k ) &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность фазы BUILD есть &amp;lt;math&amp;gt;O(kn^2)&amp;lt;/math&amp;gt; как по количеству найденных минимумов, так и по количеству операций сложения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основании формулы из описания &#039;&#039;&#039;вычислительного ядра фазы SWAP&#039;&#039;&#039; определим сложность вычисления целевой функции &amp;lt;math&amp;gt;F^i&amp;lt;/math&amp;gt; с использованием оптимизации процесса нахождения минимума (см. раздел [[#Вычислительное ядро алгоритма|Вычислительное ядро алгоритма]]). Количество операций равно:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = ( ( (1 mins)*(n-1) + (n-1) summs )*(n-k) + n*((k-1-1) mins) )*k \Rightarrow&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Rightarrow S =&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = ( ((1 mins)*(n-1) )*(n-k) + n*((k-1-1) mins) )*k = kn^2 - 3nk + k^2 &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = ( ( (n-1) summs )*(n-k) )*k = (n-1)(n-k)k &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность одной итерации фазы SWAP есть &amp;lt;math&amp;gt;O(kn^2)&amp;lt;/math&amp;gt; как по количеству найденных минимумов, так и по количеству операция сложения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Полученные оценки позволяют говорить о том, что PAM относится к алгоритмам &#039;&#039;&#039;с квадратичной сложностью&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Основная вычислительная сложность алгоритма PAM приходится на фазу SWAP, т.к. сложность одной её итерации сопоставима со сложностью всей фазы BUILD, однако SWAP может содержать в себе огромное число итераций.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
==== Информационный граф фазы BUILD ====&lt;br /&gt;
 &lt;br /&gt;
Опишем граф фазы BUILD как аналитически, так и в виде рисунка.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Граф состоит из шести групп вершин&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
# Операция M, соответствующая &#039;&#039;&#039;первой&#039;&#039;&#039; группе вершин, осуществляет изменение множества медоидов:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M_{It} = M_{It-1} \cup \overline{x}_{m_{It}}, &amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;\overline{x}_{m_{It}} = \overline{x}_{o_{It}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; (номер итерации), соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_{It}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M_{It-1}&amp;lt;/math&amp;gt; - множество медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It \leq k &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция O, соответствующая &#039;&#039;&#039;второй&#039;&#039;&#039; группе вершин, осуществляет изменение множества не-медоидов:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;O_{It} = O_{It-1} \backslash \overline{x}_{o_{It}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt;, соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_{It}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;O_{It-1}&amp;lt;/math&amp;gt; - множество не-медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It \leq k &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;третьей&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{c}=\overline{c}_{x_{o_p} } =  \begin{cases} \{ \rho (x_{o_p}, x_j ) \| 1 \leq j \leq n \}, It=1 &amp;amp; \quad\\ \{ \min ( \overline{MIN}^{(j)}, \rho (x_{o_p}, x_j) ) \| 1 \leq j \leq n \}, 1&amp;lt;It \leq k &amp;amp; \quad\\  \end{cases} .&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-It+1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = 1:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** &amp;lt;math&amp;gt;\overline{x}_{o_p}&amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;1 &amp;lt; It \leq k:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:**&amp;lt;math&amp;gt;\overline{x}_{o_p}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#:**&amp;lt;math&amp;gt;\overline{MIN}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из шестой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция S, соответствующая &#039;&#039;&#039;четвертой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline {c}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-It+1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{c}_{ x_{o_p} }&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из третьей группы с координатами &amp;lt;math&amp;gt; It, p.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M1, соответствующая &#039;&#039;&#039;пятой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M1 = (F^{It}; x_{o_{It}}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt; \begin{cases}&lt;br /&gt;
F^{It} = \min_{x_{o_p} \in O_{It-1}} S &amp;amp; \quad\\&lt;br /&gt;
x_{o_{It}} = \arg F^{It} &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из четвертой группы с первой координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;n-It+1&amp;lt;/math&amp;gt; величина.&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция MIN, соответствующая &#039;&#039;&#039;шестой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{MIN}=\overline{MIN}_{It,x_{m_{It}} } =  \begin{cases}&lt;br /&gt;
\{ \rho (x_{m_{It}            }, x_j ) \| 1 \leq j \leq n \}, It=1 &amp;amp; \quad\\&lt;br /&gt;
\{ \min ( \overline{MIN}^{(j)}, \rho (x_{m_{It}}, x_j) ) \| 1 \leq j \leq n \}, 1&amp;lt;It \leq k &amp;amp; \quad\\&lt;br /&gt;
 \end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k-1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{MIN}_{It-1,x_{m_{It-1}}} &amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из шестой группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;x_{m_{It}} =  x_{o_{It}} &amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описанный граф в общем случае представлен на Рис.1, отображен шаг с номером &amp;lt;math&amp;gt;It, 1&amp;lt;It&amp;lt;k&amp;lt;/math&amp;gt; фазы BUILD.&lt;br /&gt;
Обозначения:&lt;br /&gt;
# вершины первой группы обозначены фиолетовым цветом и подписаны как &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины  второй группы обозначены синим цветом и подписаны как &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины третьей группы обозначены жёлтым цветом и подписаны как &amp;lt;math&amp;gt;\overline{c}_{x_{o_p} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины четвертой группы обозначены серым цветом и подписаны как &amp;lt;math&amp;gt;S;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины пятой группы обозначены зеленым цветом и подписаны как &amp;lt;math&amp;gt;M1;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины шестой группы обозначены красным цветом и подписаны как &amp;lt;math&amp;gt;MIN;&amp;lt;/math&amp;gt;&lt;br /&gt;
# синим дугам сопоставлены метки, отражающие данные, используемые в соответствующих жёлтых вершинах.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Pam build 1.png|thumb|center|800px|Рисунок 1. Граф фазы BUILD алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На Рис.2 представлен граф фазы BUILD для случая &amp;lt;math&amp;gt;n=6, k=3.&amp;lt;/math&amp;gt; Вершины, соответствующие операциям, получающим входные данные и производящим выходные данные, увеличены и выделены толстыми границами.&lt;br /&gt;
&lt;br /&gt;
[[file:Pam build 2.png|thumb|center|1100px|Рисунок 2. Граф фазы BUILD алгоритма для n = 6, k = 3. ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Информационный граф фазы SWAP ====&lt;br /&gt;
 &lt;br /&gt;
Опишем граф фазы SWAP как аналитически, так и в виде рисунка.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Граф состоит из семи групп вершин&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
# Операция M, соответствующая &#039;&#039;&#039;первой&#039;&#039;&#039; группе вершин, осуществляет изменение множества медоидов.&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; (номер итерации), соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; T),&amp;lt;/math&amp;gt; принимая все целочисленные значения, где:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;T\in \N&amp;lt;/math&amp;gt; - количество выполнений фазы SWAP во время работы алгоритма PAM.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* результат срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M_{It-1}&amp;lt;/math&amp;gt; - множество медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It &amp;lt; T &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; T -1 &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = T - 1&amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы SWAP.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция O, соответствующая &#039;&#039;&#039;второй&#039;&#039;&#039; группе вершин, осуществляет изменение множества не-медоидов.&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt;, соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; T),&amp;lt;/math&amp;gt; принимая все целочисленные значения, где:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;T\in \N&amp;lt;/math&amp;gt; - количество выполнений фазы SWAP во время работы алгоритма PAM.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* результат срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;O_{It-1}&amp;lt;/math&amp;gt; - множество не-медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It &amp;lt; T &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;третьей&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{a}=\overline{a}_{x_{m_i} } = \{ \min_{ x_{m_l} \in M  \backslash \{x_{m_i}\} }  \rho ( x_{m_l},x_j ) \| 1 \leq j \leq n \}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументом операции является &amp;lt;math&amp;gt;\overline{x}_{m_i}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;четвертой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{b}=\overline{b}_{x_{m_i} x_{o_p} } =  \{ \min (\overline{a}_{ x_{m_i}}^{(j)}, \rho ( x_{o_p},x_j )) \| 1 \leq j \leq n \}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_p}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{a}_{x_{m_i}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из третьей группы с координатами &amp;lt;math&amp;gt;It, i.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция S, соответствующая &#039;&#039;&#039;пятой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline {b}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{b}_{x_{m_i} x_{o_p} }&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из четвертой группы с координатами &amp;lt;math&amp;gt;It, i, p.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M1, соответствующая &#039;&#039;&#039;шестой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M1 = (F_{x_{o_p}}^{It}; x_{o_p}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt; \begin{cases}&lt;br /&gt;
F_{x_{o_p}}^{It} = \min_{x_{o_p} \in O} S &amp;amp; \quad\\&lt;br /&gt;
x_{o_p} = \arg F_{x_{o_p}}^{It} &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из пятой группы с первыми двумя координатами &amp;lt;math&amp;gt;It, i,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;n-k&amp;lt;/math&amp;gt; величин.&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M2, соответствующая &#039;&#039;&#039;седьмой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M2 = (F_{x_{o_p}, x_{m_i}}^{It}; x_{m_i}; x_{o_p}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;\begin{cases}&lt;br /&gt;
F_{x_{o_p}, x_{m_i}}^{It} = \min (\min_{x_{m_i} \in M} (F_{x_{o_p}}^{It}), M2_{It-1}) &amp;amp; \quad\\&lt;br /&gt;
x_{m_i} = \arg \min_{x_{m_i} \in M} M1 &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M1 = (F_{x_{o_p}}^{It}; x_{o_p})&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из шестой группы с координатами &amp;lt;math&amp;gt;It, i,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; величин;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M2_{It-1}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результаты срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; T&amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = T&amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описанный граф в общем случае представлен на Рис.3, отображена одна итерация фазы SWAP.&lt;br /&gt;
Обозначения:&lt;br /&gt;
# вершины первой группы обозначены фиолетовым цветом и подписаны как &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины второй группы обозначены синим цветом и подписаны как &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины третьей группы обозначены желтым цветом и подписаны как &amp;lt;math&amp;gt;\overline{a}_{x_{m_i} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины четвертой группы обозначены оранжевым цветом и подписаны как &amp;lt;math&amp;gt;\overline{b}_{x_{m_i o_p} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины пятой группы обозначены серым цветом и подписаны как &amp;lt;math&amp;gt;S;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины шестой группы обозначены зеленым цветом и подписаны как &amp;lt;math&amp;gt;M1;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины седьмой группы обозначены красным цветом и подписаны как &amp;lt;math&amp;gt;M2;&amp;lt;/math&amp;gt;&lt;br /&gt;
# синим дугам сопоставлены метки, отражающие данные, используемые в соответствующих оранжевых вершинах;&lt;br /&gt;
# фиолетовым дугам сопоставлены метки, отражающие данные, используемые в соответствующих жёлтых вершинах.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Pam swap 1.png|thumb|center|1100px|Рисунок 3. Граф фазы SWAP алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На Рис.4 представлен граф фазы SWAP для случая &amp;lt;math&amp;gt;n=6, k=2, T=3.&amp;lt;/math&amp;gt; Вершины, соответствующие операциям, получающим входные данные и производящим выходные данные, увеличены и выделены толстыми границами.&lt;br /&gt;
&lt;br /&gt;
[[file:Pam swap 2.png|thumb|center|1100px|Рисунок 4. Граф фазы SWAP алгоритма для n = 6, k = 2, T = 3.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
При параллельной реализации алгоритма PAM будем рассматривать параллельные варианты фазы BUILD и SWAP ([[#Возможная параллельная реализация алгоритма PAM|возможная параллельная реализация]]). Покажем, что сложность фазы BUILD сопоставима со сложностью одной итерации фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
Оценки последовательной сложности фаз BUILD и SWAP приведены в параграфе &amp;quot;[[#Последовательная сложность алгоритма|Последовательная сложность алгоритма]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Ресурс параллелизма фазы BUILD ====&lt;br /&gt;
&lt;br /&gt;
Для решения задачи кластеризации методом PAM в параллельном варианте фазы BUILD в предположении доступности неограниченного числа процессов для одной итерации необходимо выполнить:&lt;br /&gt;
*  1 ярус с нахождением &amp;lt;math&amp;gt;\overline{c}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* 1 ярус с нахождением суммы &amp;lt;math&amp;gt;S:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операцию сложения;&lt;br /&gt;
* 1 ярус с нахождением значений элемента &amp;lt;math&amp;gt;M1:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &amp;lt;math&amp;gt;\overline{MIN}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It&amp;gt;1;&amp;lt;/math&amp;gt;&lt;br /&gt;
* 1 ярус с изменением множеств медоидов и не-медоидов (не выполняются операции рассматриваемых типов).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность одного шага фазы BUILD равна: &lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операция сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It=1;&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It&amp;gt;1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность фазы BUILD при числе кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; равна: &lt;br /&gt;
* &amp;lt;math&amp;gt;kn-k&amp;lt;/math&amp;gt; операция сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;3kn - 2n - \frac{1}{2}k^2 - \frac{1}{2}k&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, по сравнению с последовательным, при &amp;lt;math&amp;gt;k, n \to \infty&amp;lt;/math&amp;gt; количество операций на один порядок меньше по параметру &amp;lt;math&amp;gt;n:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt; против &amp;lt;math&amp;gt;O(kn^2).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соотношение количества сложений и взятий минимума для фазы BUILD является постоянным и стремится к &amp;lt;math&amp;gt;3,&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;k, n \to \infty.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Максимальная ширина яруса достигается при вычислении &amp;lt;math&amp;gt;\overline {c}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; и равна &amp;lt;math&amp;gt;n-It+1&amp;lt;/math&amp;gt; для шага &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; фазы BUILD. Максимальная ширина яруса при рассмотрении всей фазы есть &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и достигается на первом шаге.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Ресурс параллелизма фазы SWAP ====&lt;br /&gt;
&lt;br /&gt;
Для решения задачи кластеризации методом PAM в параллельном варианте фазы SWAP в предположении доступности неограниченного числа процессов для одной итерации необходимо выполнить:&lt;br /&gt;
* 1 ярус с нахождением &amp;lt;math&amp;gt;\overline {a}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n(k-1)&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением &amp;lt;math&amp;gt;\overline {b}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением суммы &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;:&lt;br /&gt;
** &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операцию сложения;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &#039;первого&#039; вида &amp;lt;math&amp;gt;(M1 = \min_{x_{o_p} \in O} S):&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-k-1&amp;lt;/math&amp;gt; операцию нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &#039;второго&#039; вида &amp;lt;math&amp;gt;(M2 = \min_{x_{m_i} \in M} M1):&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt; операцию нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с изменением множеств медоидов и не-медоидов (не выполняются операции рассматриваемых типов).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность одной итерации фазы SWAP равна:&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - по количеству операций сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;kn + n - 2&amp;lt;/math&amp;gt; - по количеству операций нахождений минимума для двух чисел.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, по сравнению с последовательным, при &amp;lt;math&amp;gt;k, n \to \infty&amp;lt;/math&amp;gt; количество операций на один порядок меньше по параметру &amp;lt;math&amp;gt;n:&amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt; против &amp;lt;math&amp;gt;O(kn^2).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соотношение количества сложений и взятий минимума для одной итерации фазы SWAP является постоянным и равным &amp;lt;math&amp;gt;k,&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;n \to \infty&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Максимальная ширина яруса достигается при вычислении &amp;lt;math&amp;gt;\overline {b}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; и равна &amp;lt;math&amp;gt;k(n-k).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При использовании выбранной модели, в предположении доступности неограниченного числа вычислителей, фаза BUILD при &amp;lt;math&amp;gt;n \to \infty&amp;lt;/math&amp;gt; требует большего количества операций суммирования на порядок &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, по сравнению с одной итерацией фазы SWAP. В свою очередь, количество операций подсчёта минимума ассимптотически эквивалентны.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные&#039;&#039;:&lt;br /&gt;
* число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество точек упорядоченного множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
* число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество требуемых кластеров;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов, состоящих из &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; вещественных чисел, - попарных расстояний между элементами из множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; за исключением расстояний вида &amp;lt;math&amp;gt;\rho (x, x)=0, x \in X;&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;Объём входных данных&#039;&#039;: &amp;lt;math&amp;gt;n(n-1)&amp;lt;/math&amp;gt; вещественное число и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; целых числа.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Структура хранения данных&#039;&#039;:&lt;br /&gt;
* сразу после считывания входных данных составляется квадратная симметрическая матрица &amp;lt;math&amp;gt;D^{n * n}&amp;lt;/math&amp;gt;, у которой каждый элемент &amp;lt;math&amp;gt;d_{ij}&amp;lt;/math&amp;gt; является вещественным числом - расстоянием &amp;lt;math&amp;gt;\rho (x_i, x_j);&amp;lt;/math&amp;gt;&lt;br /&gt;
* для множества медоидов &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; создаётся массив из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; целых чисел - индексов принадлежащих ему элементов из множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, аналогичный массив &amp;lt;math&amp;gt;n-k&amp;lt;/math&amp;gt; целых чисел создаётся для множества не-медоидов &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
* для пересылки данных, как правило, используется тройка &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}; x_{m_s}; x_{o_h})&amp;lt;/math&amp;gt; или пара &amp;lt;math&amp;gt;(F_{x_{o_h}}^{i_j}; x_{o_h}),&amp;lt;/math&amp;gt; где:&lt;br /&gt;
** &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; - целое число, обозначающее порядковый номер элемента множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; - целое число, обозначающее порядковый номер элемента множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;F_{x_{m_s}, x_{o_h}}^{i_j}&amp;lt;/math&amp;gt; - вещественное число, равное минимальному значению целевой функции, вычисленному в текущем контексте.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Выходные данные&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; целых чисел, составляющих множество &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; вещественное число, являющееся значением целевой функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Объём выходных данных&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;  целых чисел и &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;  вещественное.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности алгоритма является &#039;&#039;линейным&#039;&#039; и равным &amp;lt;math&amp;gt;n.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Вычислительная мощность&#039;&#039; последовательного алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, равна &amp;lt;math&amp;gt;O(T*k).&amp;lt;/math&amp;gt;&lt;br /&gt;
Вычислительная мощность параллельного алгоритма равна &amp;lt;math&amp;gt;O(T*\frac{k}{n}).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм PAM является &#039;&#039;менее чувствительным&#039;&#039; к выбросам данных, чем алгоритм k-средних. Это связано с использованием медоидов, менее подверженных влиянию таких данных.&amp;lt;ref&amp;gt; Егоров А. В., Куприянова Н. И. Особенности методов кластеризации данных // Известия Южного федерального университета. Технические науки. –2011. T. 124, № 11. –С. 174-177.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Фиксированный способ выбора начальных приближений позволяет говорить о воспроизводимости полученных результатов для последовательной реализации. Для параллельной работы алгоритма подобная воспроизводимость отсутствует, так как из-за &#039;&#039;недетерминированности&#039;&#039; выбора элементов, на которых достигается минимальное значение целевой функции для каждой итерации, итоговое множество медоидов и, следовательно, значение целевой функции может меняться.&lt;br /&gt;
&lt;br /&gt;
Алгоритм PAM &#039;&#039;конечен&#039;&#039;, так как:&lt;br /&gt;
* количество операций фазы BUILD конечно;&lt;br /&gt;
* значение целевой фукнции неотрицательно и на каждой итерации фазы SWAP строго уменьшается.&lt;br /&gt;
&lt;br /&gt;
Одно из преимуществ алгоритма PAM заключается в том, что он может работать с любой матрицей различий. В данном случае принципиальное отличие от матрицы расстояний заключается в том, что для матрицы различий может не выполняться неравенство треугольника, так как в основе её построения не обязательно используется метрика.&lt;br /&gt;
&lt;br /&gt;
Основные операция алгоритма PAM: сложение и нахождение минимума. Операция взятия минимума не подвержена процессу накопления ошибки. На каждой итерации алгоритма сложение производится над значениями, взятыми непосредственно из исходных данных. Таким образом, алгоритм PAM не накапливает ошибок в процессе своей работы и является &#039;&#039;устойчивым&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;math&amp;gt;k(n-k) \, \bmod \, p \neq 0&amp;lt;/math&amp;gt; отсутствует возможность равномерно распределить задачи рассчёта &amp;lt;math&amp;gt;\overline{b}&amp;lt;/math&amp;gt; между процессами. Кроме того, если &amp;lt;math&amp;gt;k \, \bmod \, p \neq 0&amp;lt;/math&amp;gt;, то после их распределения для некоторых процессов окажется необходимым вычислить несколько соседних значений &amp;lt;math&amp;gt;\overline{a}.&amp;lt;/math&amp;gt; Таким образом, &#039;&#039;равномерная&#039;&#039; загрузка процессов &#039;&#039;не всегда возможна&#039;&#039;. Помимо этого, агрегирование данных с целью вычисления глобального минимума приводит к простою незадействованных процессов.&lt;br /&gt;
&lt;br /&gt;
Как и большинство алгоритмов кластеризации, PAM может сходиться к некоторому &#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;
==== Возможная параллельная реализация алгоритма PAM ====&lt;br /&gt;
&lt;br /&gt;
Необходимость уменьшения времени решения задачи приводит к потребности в создании паралельной реализации алгоритма. В дальнейшем будем придерживаться следующих допущений:&lt;br /&gt;
* возможно использование &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов;&lt;br /&gt;
* не нарушая общности суждений, множества &amp;lt;math&amp;gt;M, O&amp;lt;/math&amp;gt; - упорядоченны.&lt;br /&gt;
&lt;br /&gt;
Приведённые далее возможные схемы для параллельных реализаций фазы BUILD и фазы SWAP основаны на максимально равномерном распределении задач между процессами.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Возможная параллельная реализация фазы BUILD =====&lt;br /&gt;
&lt;br /&gt;
Главная задача заключается в распараллеливании многочисленных вычислений целевой функции на каждой итерации фазы BUILD:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{o_h} \in O_{i-1}} F_{x_{o_h}}^i,&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;F_{x_{o_h}}^i = \sum_{j = 1}^{n} \overline{MIN}_{i, x_{o_h}}^{(j)},&amp;lt;/math&amp;gt; где&lt;br /&gt;
: &amp;lt;math&amp;gt;\overline{MIN}_{1, x_{o_h} \in O_0} = \{ \rho (x_{o_h}, x_j ) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{o_h} \in O_{i-1}} = \{ \min ( \overline{MIN}_{i-1, x_{m_{i-1}}}^{(j)}, \rho (x_{o_h}, x_j) ) \| 1 \leq j \leq n \}, \forall i: 1 &amp;lt; i \leq k.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Схема реализации&#039;&#039;: &amp;lt;br&amp;gt;(далее &amp;lt;math&amp;gt;0 &amp;lt; i \leq k &amp;lt;/math&amp;gt; - номер текущей итерации)&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## положим:&lt;br /&gt;
##: &amp;lt;math&amp;gt;pos = p-(n-i+1) \, \bmod \, p;&amp;lt;/math&amp;gt;&lt;br /&gt;
## на каждой итерации процессу необходимо вычислить &amp;lt;math&amp;gt;r_j&amp;lt;/math&amp;gt; значений целевой функции для соответствующих ему элементов &amp;lt;math&amp;gt;x_{o_h}, ..., x_{o_{h+(r_j-1)}}:&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt; r_j = \begin{cases}&lt;br /&gt;
    \lfloor \frac{n-i+1}{p} \rfloor , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    \lceil \frac{n-i+1}{p} \rceil , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;h = \begin{cases}&lt;br /&gt;
    r_j*j , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    (r_j-1)*pos + (j-pos)*r_j , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# каждому процессу с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## найти минимум среди значений целевой функции &amp;lt;math&amp;gt;F_{x_{o_h}}^i&amp;lt;/math&amp;gt; для каждого из значений параметра &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt; &lt;br /&gt;
##* в данном случае может быть использована оптимизация, описанная в [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]];&lt;br /&gt;
## для процессов с номером &amp;lt;math&amp;gt;j \neq 0&amp;lt;/math&amp;gt; переслать процессу с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt; пару &amp;lt;math&amp;gt;(x_{o_h}, F_{x_{o_h}}^i)&amp;lt;/math&amp;gt; для всех обработанных &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# для процесса с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;:&lt;br /&gt;
## принять пары от процессов &amp;lt;math&amp;gt;(0, p-1],&amp;lt;/math&amp;gt; в ответ на шаг 2.2;&lt;br /&gt;
## найти &amp;lt;math&amp;gt;x_{o_h},&amp;lt;/math&amp;gt; для которого целевая функция принимает минимальное значение, и положить &amp;lt;math&amp;gt;x_{m_i}:=x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
## вычислить &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{m_i}}&amp;lt;/math&amp;gt;;&lt;br /&gt;
## разослать пару &amp;lt;math&amp;gt;(x_{m_i}, \overline{MIN}_{i, x_{m_i}})&amp;lt;/math&amp;gt; при помощи широковещательной рассылки;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять пару &amp;lt;math&amp;gt;(x_{m_i}, \overline{MIN}_{i, x_{m_i}})&amp;lt;/math&amp;gt; в ответ на шаг 3.4;&lt;br /&gt;
## скорректировать локальные копии множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt;, изменив принадлежность вектора &amp;lt;math&amp;gt;x_{m_i}&amp;lt;/math&amp;gt;, а также обновить хранимое значение вектора &amp;lt;math&amp;gt;\overline{MIN}&amp;lt;/math&amp;gt; для подготовки к следующей итерации;&lt;br /&gt;
## перейти к шагу 2.1.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
После завершения &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; шагов фазы BUILD, множества &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt; (одинаковые для каждого процесса согласно приведенной схеме), а так же значение целевой функции являются выходными данными фазы BUILD.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Возможная параллельная реализация фазы SWAP =====&lt;br /&gt;
&lt;br /&gt;
Главная задача заключается в распараллеливании многократного вычисления целевой функции на каждой итерации фазы SWAP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} } \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Схема реализации&#039;&#039;: &amp;lt;br&amp;gt;(далее &amp;lt;math&amp;gt;i \in \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;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## положим:&lt;br /&gt;
##: &amp;lt;math&amp;gt;pos = p-(k*(n-k)) \, \bmod \, p;&amp;lt;/math&amp;gt;&lt;br /&gt;
## на каждой итерации процессу необходимо вычислить &amp;lt;math&amp;gt;r_j&amp;lt;/math&amp;gt; значений целевой функции для соответствующих ему пар вида (медоид, не-медоид)   &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h}), (x_{m_s}, x_{o_{h+1}}), ..., (x_{m_s}, x_{o_{n-k}}), (x_{m_{s+1}}, x_{o_0}), (x_{m_{s+1}}, x_{o_1}), . . . \, : &amp;lt;/math&amp;gt;&lt;br /&gt;
##:&amp;lt;math&amp;gt; r_j =   \begin{cases}&lt;br /&gt;
    \lfloor \frac{k*(n-k)}{p} \rfloor , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    \lceil \frac{k*(n-k)}{p} \rceil , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;s = \begin{cases}&lt;br /&gt;
    (r_j*j) \mbox{ div } (n-k) , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
     ((r_j-1)*pos + r_j*(j-pos)) \mbox{ div } (n-k), pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{m_s};&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;h = \begin{cases}&lt;br /&gt;
    (r_j*j) \, \bmod \,  (n-k) , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
     ((r_j-1)*pos + r_j*(j-pos)) \, \bmod \,  (n-k), pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# каждому процессу с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## найти минимум среди вычисленных значений целевой функции для каждого из значений первого параметра &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; по соответствующим ему &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
##* в данном случае может быть использована оптимизация, описанная в [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]];&lt;br /&gt;
## переслать процессу с номером &amp;lt;math&amp;gt;N = s \, \bmod \, p&amp;lt;/math&amp;gt; (если &amp;lt;math&amp;gt;N \neq j&amp;lt;/math&amp;gt;) тройку &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}, x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; для всех обработанных &amp;lt;math&amp;gt;x_{m_s};&amp;lt;/math&amp;gt;&lt;br /&gt;
# для процессов с номерами &amp;lt;math&amp;gt;j&amp;lt;\min (p, k):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять описанные выше тройки от процессов, обработавших элементы &amp;lt;math&amp;gt;x_{m_{z \, \bmod \, p = j}}, z = \overline {0, k-1},&amp;lt;/math&amp;gt; в ответ на шаг 2.2;&lt;br /&gt;
## вычислить минимальное среди полученных значений целевой функции;&lt;br /&gt;
## запомнить &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, на которых минимальное значение было достигнуто;&lt;br /&gt;
## при &amp;lt;math&amp;gt;j \neq 0 &amp;lt;/math&amp;gt; отправить тройку &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}, x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, соответствующую выбранной паре, процессу с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
# для процесса с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;:&lt;br /&gt;
## принять тройки от процессов &amp;lt;math&amp;gt;(0, min(k-1, p-1)],&amp;lt;/math&amp;gt; в ответ на шаг 3.4;&lt;br /&gt;
## найти пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, для которой целевая функция принимает минимальное значение;&lt;br /&gt;
## сравнить найденное минимальное значение с вычисленным значением целевой функции на предыдущей итерации фазы SWAP;&lt;br /&gt;
### (&#039;&#039; &#039;&#039;&#039;условие останова&#039;&#039;&#039; &#039;&#039;) если значение целевой функции не уменьшилось, остановить вычисление;&lt;br /&gt;
### иначе, разослать выявленную пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; при помощи широковещательной рассылки;&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; в ответ на шаг 4.3.2;&lt;br /&gt;
## скорректировать локальные копии множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt;, заменяя элемент &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; на элемент &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; и наоборот;&lt;br /&gt;
## перейти к шагу 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Ограничения и недостатки =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Ограничения&#039;&#039;:&lt;br /&gt;
* предполагается, что матрица расстояний &amp;lt;math&amp;gt;D^{n * n}&amp;lt;/math&amp;gt; полностью помещается в памяти каждого процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Недостатки&#039;&#039;:&lt;br /&gt;
* при распределении обсчитываемых целевых функций, каждому из процессов ставится в соответствие некоторая совокупность пар &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, для которых нужно рассчитать значения целевой функции. В случае, если количество процессов не кратно количеству обрабатываемых кластеров, различные процессы получат пары у которых совпадают &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt;, что приведёт к совершению одинаковых вычислений на различных процессах: &amp;lt;math&amp;gt;   \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )), 1 \leq j \leq n;&amp;lt;/math&amp;gt;&lt;br /&gt;
* вычисление фазы SWAP успешно распараллеливается между &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессами, однако после этого происходит агрегация данных в 2 этапа относительно &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; для вычисления глобального минимума. На первом этапе данные собираются на первых &amp;lt;math&amp;gt;\min (p,k)&amp;lt;/math&amp;gt; процессах, где происходят локальные вычисления минимумов среди принятых данных (для каждого &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt;), после чего полученные минимумы и связанная с ними информация агрегируются на мастер-процессе, который вычисляет глобальный минимум и извещает о нём все остальные процессы. &amp;lt;br&amp;gt;Во время описанных вычислений все незадействованные процессы простаивают.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Дополнительные возможности&#039;&#039;:&lt;br /&gt;
* помимо описанной схемы, также есть возможность распараллелить операцию вычисления матрицы расстояний &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, однако это является отдельной алгоритмической задачей и не даёт существенного прироста производительности алгоритма.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Существующие параллельные реализации алгоритма PAM ====&lt;br /&gt;
&lt;br /&gt;
Примером другой параллельной реализации алгоритма PAM может служить реализация в пакете SPRINT для языка R (подробнее см. [[#Существующие реализации алгоритма|существующие реализации алгоритма]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Структура графа алгоритма (см. 1.7 [[#Информационный граф| Информационный граф алгоритма]]) такова, что позволяет надеяться на получение хорошей масштабируемости.&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма Partitioning Around Medoids проводилось на суперкомпьютере BlueGene/P &amp;lt;ref&amp;gt;IBM BlueGene/P  - [http://hpc.cmc.msu.ru http://hpc.cmc.msu.ru]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
* число процессоров:&lt;br /&gt;
** [16 : 128] с шагом по степеням двойки;&lt;br /&gt;
** [256 : 1024] с шагом 128;&lt;br /&gt;
* размер матрицы (n):&lt;br /&gt;
** [25 : 150] с шагом 25;&lt;br /&gt;
** 200;&lt;br /&gt;
** [250 : 5000] с шагом 250.&lt;br /&gt;
&lt;br /&gt;
Особенности проведения экспериментов:&lt;br /&gt;
* тестовые данные являются псевдослучайными;&lt;br /&gt;
* для всех экспериментов использовался одинаковый набор данных;&lt;br /&gt;
* количество кластеров линейно зависит от размера матрицы:&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;250, \, k=n \mbox{ div }10;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;gt;=250, \, k=n \mbox{ div }50.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
* минимальная эффективность реализации: 0,024% достигается при использовании 1024 процессоров для матрицы размера 25x25;&lt;br /&gt;
* максимальная эффективность реализации: 97,844% достигается при использовании 16 процессоров для матрицы размера 2000x2000.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации PAM в зависимости от изменяемых параметров запуска:&lt;br /&gt;
&lt;br /&gt;
[[file:PAM gflops.png|thumb|center|800px|Рисунок 3. Параллельная реализация алгоритма PAM. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
[[file:PAM efficiency.png|thumb|center|800px|Рисунок 4. Параллельная реализация алгоритма PAM. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости выбранной реализации алгоритма PAM:&lt;br /&gt;
* По числу процессов: -0.005745. С ростом числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается. Этот результат вызван ростом времени, затрачиваемого на пересылку данных, то есть ростом накладных расходов на организацию параллельного выполнения.&lt;br /&gt;
* По размеру задачи: 0.00105. С ростом размера задачи эффективность на рассмотренной области изменений параметров запуска увеличивается. Этот результат вызван увеличением количества вычислений относительно объема пересылок данных.&lt;br /&gt;
* Общая оценка масштабируемости: 0.000073. При рассмотрении области параметров запуска в целом, можно говорить о том, что с ростом размера задачи и числа процессов эффективность увеличивается, однако является достаточно низкой.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/phonexicum/pam-mpi-cmc Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# Последовательная реализация алгоритма PAM в пакете ClusterR на языке R:&lt;br /&gt;
#* Лицензия: MIT&lt;br /&gt;
#* [https://cran.r-project.org/package=ClusterR веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в функции &#039;Cluster_Medoids&#039;. Отличительная особенность реализации &amp;lt;ref&amp;gt;Lampros Mouselimis [https://cran.r-project.org/web/packages/cluster/cluster.pdf Package &#039;ClusterR&#039;]. October 8, 2016&amp;lt;/ref&amp;gt;:&lt;br /&gt;
#** для задания метрики между элементами кластеризуемого множества передаётся строка, задающая одну из реализованных в алгоритме метрик. Данный подход теряет одно из преимуществ алгоритма PAM, позволяющее в качестве матрицы расстояний использовать произвольную матрицу различий.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Последовательная реализация алгоритма PAM в пакете Cluster на языке R:&lt;br /&gt;
#* Лицензия: GPL (≥2)&lt;br /&gt;
#* [https://cran.r-project.org/package=cluster веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в функции &#039;pam()&#039;. Данная реализация имеет следующие особенности &amp;lt;ref&amp;gt;Martin Maechler., etc. [https://cran.r-project.org/web/packages/cluster/cluster.pdf Package &#039;cluster&#039;]. October 8, 2016&amp;lt;/ref&amp;gt;:&lt;br /&gt;
#** функция может принимать на вход не множество точек, а матрицу расстояний между ними;&lt;br /&gt;
#** реализация более гибкая, так как принимает на вход матрицу различий элементов, а не использует какую-либо метрику;&lt;br /&gt;
#** может быть предоставлено графическое отображение.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Параллельная реализация алгоритма PAM в пакете SPRINT (Simple Parallel R INTerface - параллельный фреймворк) на языке R:&lt;br /&gt;
#* Лицензия: GPL (≥3)&lt;br /&gt;
#* [https://cran.r-project.org/package=sprint веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в фукции &#039;ppam()&#039;. Входные параметры данной функции схожи с параметрами, задаваемыми в линейной реализации &#039;pam()&#039; пакета Cluster языка R. Отличительной особенностью является подача на вход предвычисленной матрицы расстояний (например, с помощью функции &#039;pcor()&#039; из этой же библиотеки).&amp;lt;ref&amp;gt;University of Edinburgh SPRINT Team. [https://cran.r-project.org/web/packages/sprint/sprint.pdf Package &#039;sprint&#039;]. February 20, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Параллельная реализация алгоритма PAM на основе операций MapReduce на Hadoop кластере.&lt;br /&gt;
#* В рамках исследования по ускорению анализа информации о геноме были созданы реализации алгоритма PAM с использованием технологии MPI и технологии MapReduce. Реализация в открытом досупе отсутствует. &amp;lt;ref&amp;gt;Dobrzelecki B. et al. Managing and analysing Genomic Data using HPC and Clouds //Grid and Cloud Database Management. – Springer Berlin Heidelberg, 2011. – С. 261-277.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
MKL, ScaLAPACK, PETSc, FFTW, ATLAS, Magma и другие подобные библиотеки.&lt;br /&gt;
&lt;br /&gt;
* Дать ссылки на существующие последовательные и параллельные реализации алгоритма (&amp;quot;уже доступные&amp;quot;)&lt;br /&gt;
* Реализация - коммерческая/свободная, лицензия&lt;br /&gt;
* ссылка на дистрибутив и описание&lt;br /&gt;
* особенности, достоинства/недостатки, ....&lt;br /&gt;
&lt;br /&gt;
гугл-запрос: &amp;quot;partitioning around medoids&amp;quot; &amp;quot;PAM&amp;quot; BUILD SWAP &amp;quot;MPI&amp;quot; &amp;quot;program&amp;quot; &amp;quot;package&amp;quot; -worldwidescience&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Anastasia</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:Avasilenko/Partitioning_Around_Medoids_(PAM)&amp;diff=11848</id>
		<title>Участник:Avasilenko/Partitioning Around Medoids (PAM)</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:Avasilenko/Partitioning_Around_Medoids_(PAM)&amp;diff=11848"/>
		<updated>2016-10-15T20:37:20Z</updated>

		<summary type="html">&lt;p&gt;Anastasia: /* Информационный граф фазы SWAP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Partitioning Around Medoids&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(T*kn^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*(n-1)+2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;k+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(T*kn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(k(n-k))&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Авторы&#039;&#039;&#039;:&lt;br /&gt;
* [[Участник:Avasilenko|А.Э.Василенко]] (отвечает за программистскую составляющую);&lt;br /&gt;
* [[Участник:Anastasia|А.В.Тузикова]] (отвечает за математическую составляющую).&lt;br /&gt;
Вклад авторов считать равноценным, чётких границ ответственности провести невозможно.&lt;br /&gt;
&lt;br /&gt;
==Свойства и структура алгоритма==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
 &lt;br /&gt;
Объединение схожих объектов в группы - один из важнейших видов человеческой деятельности&amp;lt;ref&amp;gt;Rousseeuw P. J., Kaufman L. Finding Groups in Data. – Wiley Online Library, 1990.&amp;lt;/ref&amp;gt;. Более того - это важная часть процесса познания мира, в котором мы живем. Мы учим детей различать кошек и собак, воду и песок, мужчин и женщин путем постоянного развития и улучшения подсознательных схем классификации. Примеры есть и во взрослой жизни – в химии необходимо классифицировать соединения, в археологии – объединять находки по периодам и т.д.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задача кластеризации&#039;&#039;&#039; - разделение множества объектов на заданное число множеств с минимизацией некоторого функционала - является популярной задачей, относится к разделу машинного обучения и находит применение в таких областях, как анализ текста, биоинформатика, интеллектуальные транспортные системы и др. &amp;lt;ref&amp;gt; Речкалов Т.В. Параллельный алгоритм кластеризации для многоядерного сопроцессора Intel Xeon Phi // Суперкомпьютерные дни в России: Труды vеждународной конференции. – М.: Изд-во МГУ, 2015, c. 532.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PAM&#039;&#039;&#039; (&#039;&#039;&#039;Partitioning Around Medoids&#039;&#039;&#039;) - плоский алгоритм кластеризации, позволяющй выделить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров (множеств), удовлетворяющих следующим свойствам:&lt;br /&gt;
 &lt;br /&gt;
*   каждая группа содержит хотя бы один объект;&lt;br /&gt;
*   каждый объект принадлежит ровно одной группе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Модель &amp;lt;ref&amp;gt;Kaufman, L. and Rousseeuw, P.J., Clustering by means of Medoids. In: Y. Dodge and North-Holland, editor. Statistical Data Analysis Based on the L1-Norm and Related Methods. Springer US; 1987, p. 405–416.&amp;lt;/ref&amp;gt;, лежащая в основе алгоритма PAM, основана на выборе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов, являющихся характерными точками соответствующего кластера. Таким образом, кластерам сопоставляются принадлежащие им объекты, называемые &#039;&#039;&#039;медоидами&#039;&#039;&#039;, на основании которых распределяются остальные объекты по принципу наибольшего сходства. Cама модель называется моделью &#039;&#039;&#039;k-medoids&#039;&#039;&#039; (не путать с моделью &#039;&#039;k-median&#039;&#039;).&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
PAM состоит из двух фаз: &#039;&#039;&#039;BUILD&#039;&#039;&#039; и &#039;&#039;&#039;SWAP&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
*   на фазе BUILD выполняется первичная кластеризация, в ходе которой последовательно выбираются &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов в качестве медоидов;&lt;br /&gt;
*   фаза SWAP представляет собой итерационный процесс, в ходе которого производятся попытки улучшить множество медоидов. Алгоритм выполняет поиск пары объектов (медоид, не-медоид), минимизирующих целевую функцию при замене, после чего обновляет множество медоидов.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации алгоритма выбирается пара (медоид, не-медоид) такая, что замена медоида &amp;lt;math&amp;gt;x_{m_l}&amp;lt;/math&amp;gt; на не-медоид &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; дает лучшую кластеризацию из возможных. Оценка кластеризации выполняется с помощью целевой функции, вычисляемой как сумма расстояний от каждого объекта до ближайшего медоида:&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;E = \sum_{j = 1}^n \min_{1 \leq l \leq k} \rho ( x_{m_l},x_{o_h} )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Процедура изменения множества медоидов повторяется, пока есть возможность улучшения значения целевой функции.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Исходные данные&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
*   множество кластеризуемых объектов &amp;lt;math&amp;gt;X = \{ x_1, x_2, ... , x_n \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; - кортеж, состоящий из &amp;lt;math&amp;gt; w &amp;lt;/math&amp;gt; вещественных чисел;&lt;br /&gt;
*   симметрическая матрица &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, элементы матрицы &amp;lt;math&amp;gt;d_{ij}=d(i,j)&amp;lt;/math&amp;gt; - вычисленные расстояния между объектами &amp;lt;math&amp;gt;x_i, x_j&amp;lt;/math&amp;gt;;&lt;br /&gt;
*   количество кластеров &amp;lt;math&amp;gt;k \leq n.&amp;lt;/math&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Обозначения&#039;&#039;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;M = \{ x_{m_1}, x_{m_2}, ... , x_{m_k} \} &amp;lt;/math&amp;gt; - множество медоидов, &amp;lt;math&amp;gt; M \subseteq X ;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;O = \{ x_{o_1}, x_{o_2}, ... , x_{o_r} \} &amp;lt;/math&amp;gt; - множество не-медоидов, &amp;lt;math&amp;gt; O \subseteq X, &amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;r=n-k;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;d_{ij}=\rho (x_i, x_j )&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \rho  : X \times X \rightarrow R &amp;lt;/math&amp;gt; — метрика расстояния;&lt;br /&gt;
*   &amp;lt;math&amp;gt;F_{M,O} = \sum_{j = 1}^{n} \min_{ x_{m_l} \in M} \rho ( x_{m_l},x_{o_j} )&amp;lt;/math&amp;gt; - значение целевой функции для заданных множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
*   &amp;lt;math&amp;gt;T^i&amp;lt;/math&amp;gt; - изменение целевой функции на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-м шаге фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Выходные данные&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;M = \{ x_{m_1}, x_{m_2}, ... , x_{m_k} \}&amp;lt;/math&amp;gt; - множество медоидов;&lt;br /&gt;
* &amp;lt;math&amp;gt;K_{m_i} = \{ x_{o_h} \in O \| x_{m_i} = \arg \min_{x_{m_s} \in M} \rho (x_{o_h}, x_{m_s}) \}, 1 \leq i \leq k&amp;lt;/math&amp;gt; - искомые кластеры.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Вычислительные формулы метода&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
*   &#039;&#039;фаза BUILD&#039;&#039; (состоит из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; шагов последовательного выбора &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; медоидов):&lt;br /&gt;
**   &amp;lt;math&amp;gt;O_0 = X, M_0 = \varnothing ;&amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_1} = \arg \min_{x_{o_h} \in O_0} \sum_{j = 1}^n \rho \left ( x_{o_h},x_j \right ), O_1 = O_0 \backslash \{x_{m_1}\}, M_1 = M_1 \cup \{x_{m_1}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_2} = \arg \min_{x_{o_h} \in O_1} \sum_{j = 1}^{n} \min ( \rho ( x_{m_1},x_j ), \rho ( x_{o_h},x_j ) ), O_2 = O_1 \backslash \{x_{m_2}\}, M_2 = M_1 \cup \{x_{m_2}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_3} = \arg \min_{x_{o_h} \in O_2} \sum_{j = 1}^{n} \min_{1 \leq l \leq 2} ( \rho ( x_{m_l},x_j ) , \rho ( x_{o_h},x_j ) ) , O_3 = O_2 \backslash \{x_{m_3}\}, M_3 = M_3 \cup \{x_{m_3}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
** ...&lt;br /&gt;
**   &amp;lt;math&amp;gt;x_{m_k} = \arg \min_{x_{o_h} \in O_{k-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{k-1}} ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j ) ) , O_k = O_{k-1} \backslash \{x_{m_k}\}, M_k = M_{k-1} \cup \{x_{m_k}\} ; &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;фаза SWAP&#039;&#039; (итерационный процесс):&lt;br /&gt;
** начальное приближение: &amp;lt;math&amp;gt;O_0 = O_k^{BUILD}, M_0 = M_k^{BUILD};&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й шаг итерации:&lt;br /&gt;
*** вычисление целевой функции при оптимальной замене (замене, при которой достигается лучшая кластеризация из возможных на текущей итерации): &amp;lt;br&amp;gt;&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j) ); &amp;lt;/math&amp;gt;&lt;br /&gt;
*** определение пары (медоид, не-медоид), на которой достигается оптимальная замена: &amp;lt;br&amp;gt;&amp;lt;math&amp;gt; (x_{m_s}, x_{o_h}) = \arg F^i; &amp;lt;/math&amp;gt;&lt;br /&gt;
*** проверка критерия останова;&lt;br /&gt;
*** изменение множеств в соответствии с выбранной парой &amp;lt;math&amp;gt; (x_{m_s}, x_{o_h}):&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&amp;lt;math&amp;gt;M_i = M_{i-1} \backslash \{x_{m_s}\} \cup \{x_{o_h}\} , O_i = O_{i-1} \cup \{x_{m_s}\} \backslash \{x_{o_h}\} ;&amp;lt;/math&amp;gt;&lt;br /&gt;
** критерий останова:&lt;br /&gt;
*** &amp;lt;math&amp;gt;T^i = F^{i-1} - F^{i} \leq 0 .&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро алгоритма PAM на этапе BUILD&#039;&#039;&#039; состоит из множественных вычислений значений целевой функции при различных вариантах выбора дополнительного медоида (шаг алгоритма &amp;lt;math&amp;gt;1 \leq i \leq k&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1}} ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j ) ) = \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \overline{MIN}_{i, x_{o_h}}^{(j)},&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где:&lt;br /&gt;
* &amp;lt;math&amp;gt;\overline{MIN}_{1, x_{o_h} \in O_0} = \{ \rho (x_{o_h}, x_j ) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{o_h} \in O_{i-1}} = \{ \min ( \overline{MIN}_{i-1, x_{m_{i-1}}}^{(j)}, \rho (x_{o_h}, x_j) ) \| 1 \leq j \leq n \}, \forall i: 1 &amp;lt; i \leq k.&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;|O_{i-1}| = n-i+1&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Оптимизация&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* таким образом, на каждой последующей итерации можно использовать величину, вычисленную на предыдущем шаге, что позволяет сократить число вычислений минимумов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычислительное ядро алгоритма PAM на этапе SWAP&#039;&#039;&#039; состоит из множественных вычислений значений целевой функции при различных вариантах замены некоторого существующего медоида на элемент из числа не-медоидов. &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-я итерация фазы SWAP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} , x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j ), \rho ( x_{o_h},x_j) ) =&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;= \min_{x_{m_s} \in M_{i-1} } \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Оптимизация&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* таким образом, при поиске пары (медоид, не-медоид), наилучшим образом минимизирующей целевую функцию, происходит поиск минимума по всем возможным элементам &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, для которых вычисляется &amp;lt;math&amp;gt;\sum_{j = 1}^{n} \min (a, b)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt; \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )),&amp;lt;/math&amp;gt; и является инвариантом по отношению к &amp;lt;math&amp;gt;\min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) ),&amp;lt;/math&amp;gt; что позволяет предвычислить элемент &amp;lt;math&amp;gt;a.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Нахождение расстояния между двумя объектами &amp;lt;math&amp;gt;\rho \left ( p, q \right )&amp;lt;/math&amp;gt; является макрооперацией в том случае, если на вход алгоритму подавалась не матрица расстояний, а набор точек с их координатами в пространстве &amp;lt;math&amp;gt;R^w&amp;lt;/math&amp;gt;.&lt;br /&gt;
В этом случае может быть использована, например, евклидова метрика:&lt;br /&gt;
:&amp;lt;math&amp;gt;d(p,q)=\sqrt{(p_1-q_1)^2+(p_2-q_2)^2+\dots+(p_w-q_w)^2} = \sqrt{\sum_{j=1}^w (p_j-q_j)^2} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p, q \in R^w.&amp;lt;/math&amp;gt;&lt;br /&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;&#039;&#039;  : Множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; или матрица расстояний &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, количество кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;&lt;br /&gt;
 &#039;&#039;&#039;Выход&#039;&#039;&#039; : Множество медоидов &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
 0  Если на вход было подано множество объектов, необходимо предварительно вычислить матрицу расстояний;&lt;br /&gt;
 1  Инициализация множеств &amp;lt;math&amp;gt;M, O&amp;lt;/math&amp;gt;; // фаза BUILD&lt;br /&gt;
 2  &#039;&#039;&#039;while (1)&#039;&#039;&#039; { // фаза SWAP&lt;br /&gt;
 3      Вычислить &amp;lt;math&amp;gt;F^i&amp;lt;/math&amp;gt; и соответствующие ей &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;;// вычисление проводить с учётом приведённой ранее оптимизации (см. 1.3 [[#Вычислительное ядро алгоритма|Вычислительное ядро алгоритма]]);&lt;br /&gt;
 4      Вычислить &amp;lt;math&amp;gt;T^i&amp;lt;/math&amp;gt;;&lt;br /&gt;
 5      &#039;&#039;&#039;if&#039;&#039;&#039; (&amp;lt;math&amp;gt;T^i &amp;gt; 0&amp;lt;/math&amp;gt;) {&lt;br /&gt;
 6          Обновить множества &amp;lt;math&amp;gt;M, O&amp;lt;/math&amp;gt;;&lt;br /&gt;
 7      } &#039;&#039;&#039;else&#039;&#039;&#039; {&lt;br /&gt;
 8          &#039;&#039;&#039;break&#039;&#039;&#039;;&lt;br /&gt;
 9      }&lt;br /&gt;
 10 };&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Оптимизации&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Предвычисление матрицы расстояний&#039;&#039;&#039;. Необходимо предварительно вычислить матрицу расстояний и сохранить её в памяти, так как в ходе вычисления алгоритма многократно используются расстояния между элементами, а вычисление каждого из них является ресурсоёмкой операцией из нескольких умножений и одного извлечения квадратного корня.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Минимизация кеш-промахов&#039;&#039;&#039;. Матрица расстояний, к которой постоянно выполняется доступ на чтение для вычисления минимумов и их суммирования, должна храниться в памяти как матрица размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, несмотря на то, что она симметрическая и достаточно хранить лишь половину (элементы над или под главной диагональю). Данная оптимизация потребует использования в 2 раза большего количества памяти для хранения расстояний (а это является главным расходом памяти программы, так как все остальные используемые данные являются временными (локальными для каждой операции) и представляют из себя несколько векторов длинной &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов). Однако так как в данном алгоритме доступ к матрице осуществляется построчно (в  [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]] поэлементно ищутся  минимумы 2-х векторов, после чего все они складываются), то в этом случае из матрицы можно будет читать данные по строкам подряд, что снижает количество кеш-промахов. Использование только половины матрицы приводит к частым промахам в кеше в связи с необходимостью загрузки части векторов по строкам, а части - по столбцам.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления &#039;&#039;&#039;матрицы расстояний&#039;&#039;&#039; требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций вычисления расстояний;&lt;br /&gt;
* сложность каждой операции вычисления расстояния (для случая использования Евклидовой метрики) равна &amp;lt;math&amp;gt;2*w-1&amp;lt;/math&amp;gt; операций сложения и вычитания, &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; операций возведения в квадрат (умножения) и &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операции извлечения квадратного корня.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основании формулы из описания &#039;&#039;&#039;вычислительного ядра фазы BUILD&#039;&#039;&#039; определим сложность выполнения всего этапа.&lt;br /&gt;
&lt;br /&gt;
Обозначим:&lt;br /&gt;
*&amp;lt;math&amp;gt;summs&amp;lt;/math&amp;gt; - операция сложения двух вещественных чисел;&lt;br /&gt;
*&amp;lt;math&amp;gt;mins&amp;lt;/math&amp;gt; - операция нахождения минимума для двух вещественных чисел.&lt;br /&gt;
&lt;br /&gt;
Тогда, количество операций равно:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = ( ( (n-1) summs ) * (n-1+1) + (n-1+1-1)mins) + \sum_{i = 2}^{k} ( ( (1 mins)*(n-1) + (n-1) summs ) * (n-i+1) + (n-i+1-1)mins) \Rightarrow&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Rightarrow S =&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = ( ( 0 ) * (n-1+1) + (n-1+1-1)mins) + \sum_{i = 2}^{k} ( ( (1 mins)*(n-1)) * (n-i+1) + (n-i+1-1)mins ) &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = \sum_{i = 1}^{k} ( ( (n-1) summs ) * (n-i+1) ) &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
=&lt;br /&gt;
&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;&lt;br /&gt;
=&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = n^2(k-1) - \frac{1}{2}(nk^2 - nk) + n - k &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = n^2k - \frac{1}{2}(nk^2 + nk - k^2 + k ) &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность фазы BUILD есть &amp;lt;math&amp;gt;O(kn^2)&amp;lt;/math&amp;gt; как по количеству найденных минимумов, так и по количеству операций сложения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На основании формулы из описания &#039;&#039;&#039;вычислительного ядра фазы SWAP&#039;&#039;&#039; определим сложность вычисления целевой функции &amp;lt;math&amp;gt;F^i&amp;lt;/math&amp;gt; с использованием оптимизации процесса нахождения минимума (см. раздел [[#Вычислительное ядро алгоритма|Вычислительное ядро алгоритма]]). Количество операций равно:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S = ( ( (1 mins)*(n-1) + (n-1) summs )*(n-k) + n*((k-1-1) mins) )*k \Rightarrow&amp;lt;/math&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Rightarrow S =&lt;br /&gt;
  \begin{cases}&lt;br /&gt;
    S(mins) = ( ((1 mins)*(n-1) )*(n-k) + n*((k-1-1) mins) )*k = kn^2 - 3nk + k^2 &amp;amp; \quad\\&lt;br /&gt;
    S(summs) = ( ( (n-1) summs )*(n-k) )*k = (n-1)(n-k)k &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, сложность одной итерации фазы SWAP есть &amp;lt;math&amp;gt;O(kn^2)&amp;lt;/math&amp;gt; как по количеству найденных минимумов, так и по количеству операция сложения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Полученные оценки позволяют говорить о том, что PAM относится к алгоритмам &#039;&#039;&#039;с квадратичной сложностью&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Основная вычислительная сложность алгоритма PAM приходится на фазу SWAP, т.к. сложность одной её итерации сопоставима со сложностью всей фазы BUILD, однако SWAP может содержать в себе огромное число итераций.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
==== Информационный граф фазы BUILD ====&lt;br /&gt;
 &lt;br /&gt;
Опишем граф фазы BUILD как аналитически, так и в виде рисунка.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Граф состоит из шести групп вершин&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
# Операция M, соответствующая &#039;&#039;&#039;первой&#039;&#039;&#039; группе вершин, осуществляет изменение множества медоидов:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M_{It} = M_{It-1} \cup \overline{x}_{m_{It}}, &amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;\overline{x}_{m_{It}} = \overline{x}_{o_{It}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; (номер итерации), соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_{It}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M_{It-1}&amp;lt;/math&amp;gt; - множество медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It \leq k &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция O, соответствующая &#039;&#039;&#039;второй&#039;&#039;&#039; группе вершин, осуществляет изменение множества не-медоидов:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;O_{It} = O_{It-1} \backslash \overline{x}_{o_{It}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt;, соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_{It}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;O_{It-1}&amp;lt;/math&amp;gt; - множество не-медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It \leq k &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;третьей&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{c}=\overline{c}_{x_{o_p} } =  \begin{cases} \{ \rho (x_{o_p}, x_j ) \| 1 \leq j \leq n \}, It=1 &amp;amp; \quad\\ \{ \min ( \overline{MIN}^{(j)}, \rho (x_{o_p}, x_j) ) \| 1 \leq j \leq n \}, 1&amp;lt;It \leq k &amp;amp; \quad\\  \end{cases} .&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-It+1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = 1:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** &amp;lt;math&amp;gt;\overline{x}_{o_p}&amp;lt;/math&amp;gt; - входное данное алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;1 &amp;lt; It \leq k:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:**&amp;lt;math&amp;gt;\overline{x}_{o_p}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#:**&amp;lt;math&amp;gt;\overline{MIN}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из шестой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция S, соответствующая &#039;&#039;&#039;четвертой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline {c}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-It+1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{c}_{ x_{o_p} }&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из третьей группы с координатами &amp;lt;math&amp;gt; It, p.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M1, соответствующая &#039;&#039;&#039;пятой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M1 = (F^{It}; x_{o_{It}}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt; \begin{cases}&lt;br /&gt;
F^{It} = \min_{x_{o_p} \in O_{It-1}} S &amp;amp; \quad\\&lt;br /&gt;
x_{o_{It}} = \arg F^{It} &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из четвертой группы с первой координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;n-It+1&amp;lt;/math&amp;gt; величина.&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; k &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = k &amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы BUILD.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция MIN, соответствующая &#039;&#039;&#039;шестой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{MIN}=\overline{MIN}_{It,x_{m_{It}} } =  \begin{cases}&lt;br /&gt;
\{ \rho (x_{m_{It}            }, x_j ) \| 1 \leq j \leq n \}, It=1 &amp;amp; \quad\\&lt;br /&gt;
\{ \min ( \overline{MIN}^{(j)}, \rho (x_{m_{It}}, x_j) ) \| 1 \leq j \leq n \}, 1&amp;lt;It \leq k &amp;amp; \quad\\&lt;br /&gt;
 \end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k-1],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{MIN}_{It-1,x_{m_{It-1}}} &amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из шестой группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;x_{m_{It}} =  x_{o_{It}} &amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из пятой группы с координатой &amp;lt;math&amp;gt;It.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описанный граф в общем случае представлен на Рис.1, отображен шаг с номером &amp;lt;math&amp;gt;It, 1&amp;lt;It&amp;lt;k&amp;lt;/math&amp;gt; фазы BUILD.&lt;br /&gt;
Обозначения:&lt;br /&gt;
# вершины первой группы обозначены фиолетовым цветом и подписаны как &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины  второй группы обозначены синим цветом и подписаны как &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины третьей группы обозначены жёлтым цветом и подписаны как &amp;lt;math&amp;gt;\overline{c}_{x_{o_p} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины четвертой группы обозначены серым цветом и подписаны как &amp;lt;math&amp;gt;S;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины пятой группы обозначены зеленым цветом и подписаны как &amp;lt;math&amp;gt;M1;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины шестой группы обозначены красным цветом и подписаны как &amp;lt;math&amp;gt;MIN;&amp;lt;/math&amp;gt;&lt;br /&gt;
# синим дугам сопоставлены метки, отражающие данные, используемые в соответствующих жёлтых вершинах.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Pam build 1.png|thumb|center|800px|Рисунок 1. Граф фазы BUILD алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На Рис.2 представлен граф фазы BUILD для случая &amp;lt;math&amp;gt;n=6, k=3.&amp;lt;/math&amp;gt; Вершины, соответствующие операциям, получающим входные данные и производящим выходные данные, увеличены и выделены толстыми границами.&lt;br /&gt;
&lt;br /&gt;
[[file:Pam build 2.png|thumb|center|1100px|Рисунок 2. Граф фазы BUILD алгоритма для n = 6, k = 3. ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Информационный граф фазы SWAP ====&lt;br /&gt;
 &lt;br /&gt;
Опишем граф фазы SWAP как аналитически, так и в виде рисунка.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;Граф состоит из семи групп вершин&#039;&#039;:&lt;br /&gt;
 &lt;br /&gt;
# Операция M, соответствующая &#039;&#039;&#039;первой&#039;&#039;&#039; группе вершин, осуществляет изменение множества медоидов.&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; (номер итерации), соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; T),&amp;lt;/math&amp;gt; принимая все целочисленные значения, где:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;T\in \N&amp;lt;/math&amp;gt; - количество выполнений фазы SWAP во время работы алгоритма PAM.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* результат срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M_{It-1}&amp;lt;/math&amp;gt; - множество медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It &amp;lt; T &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; T -1 &amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = T - 1&amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы SWAP.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция O, соответствующая &#039;&#039;&#039;второй&#039;&#039;&#039; группе вершин, осуществляет изменение множества не-медоидов.&lt;br /&gt;
#: Единственная координата &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt;, соответствующая каждой из вершин, меняется в диапазоне &amp;lt;math&amp;gt;[1; T),&amp;lt;/math&amp;gt; принимая все целочисленные значения, где:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;T\in \N&amp;lt;/math&amp;gt; - количество выполнений фазы SWAP во время работы алгоритма PAM.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* результат срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It,&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;O_{It-1}&amp;lt;/math&amp;gt; - множество не-медоидов:&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1 &amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;1&amp;lt; It &amp;lt; T &amp;lt;/math&amp;gt; -  результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;третьей&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{a}=\overline{a}_{x_{m_i} } = \{ \min_{ x_{m_l} \in M  \backslash \{x_{m_i}\} }  \rho ( x_{m_l},x_j ) \| 1 \leq j \leq n \}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументом операции является &amp;lt;math&amp;gt;\overline{x}_{m_i}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из первой группы с координатой &amp;lt;math&amp;gt;It-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция, соответствующая &#039;&#039;&#039;четвертой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;\overline{b}=\overline{b}_{x_{m_i} x_{o_p} } =  \{ \min (\overline{a}_{ x_{m_i}}^{(j)}, \rho ( x_{o_p},x_j )) \| 1 \leq j \leq n \}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{x}_{o_p}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из второй группы с координатой &amp;lt;math&amp;gt;It-1&amp;lt;/math&amp;gt;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{a}_{x_{m_i}}&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из третьей группы с координатами &amp;lt;math&amp;gt;It, i.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция S, соответствующая &#039;&#039;&#039;пятой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;S = \sum_{j = 1}^{n} \overline {b}^{(j)}.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&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; n-k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;\overline{b}_{x_{m_i} x_{o_p} }&amp;lt;/math&amp;gt; - результат срабатывания операции, соответствующей вершине из четвертой группы с координатами &amp;lt;math&amp;gt;It, i, p.&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M1, соответствующая &#039;&#039;&#039;шестой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M1 = (F_{x_{o_p}}^{It}; x_{o_p}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt; \begin{cases}&lt;br /&gt;
F_{x_{o_p}}^{It} = \min_{x_{o_p} \in O} S &amp;amp; \quad\\&lt;br /&gt;
x_{o_p} = \arg F_{x_{o_p}}^{It} &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; k],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из пятой группы с первыми двумя координатами &amp;lt;math&amp;gt;It, i,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;n-k&amp;lt;/math&amp;gt; величин.&lt;br /&gt;
#: Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
#:&lt;br /&gt;
#: &amp;lt;br&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
# Операция M2, соответствующая &#039;&#039;&#039;седьмой&#039;&#039;&#039; группе вершин, выглядит следующим образом:&lt;br /&gt;
#:: &amp;lt;math&amp;gt;M2 = (F_{x_{o_p}, x_{m_i}}^{It}; x_{m_i}; x_{o_p}),&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;\begin{cases}&lt;br /&gt;
F_{x_{o_p}, x_{m_i}}^{It} = \min (\min_{x_{m_i} \in M} (F_{x_{o_p}}^{It}), M2_{It-1}) &amp;amp; \quad\\&lt;br /&gt;
x_{m_i} = \arg \min_{x_{m_i} \in M} M1 &amp;amp; \quad\\&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Координаты вершин:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; - меняется в диапазоне &amp;lt;math&amp;gt;[1; T],&amp;lt;/math&amp;gt; принимая все целочисленные значения.&lt;br /&gt;
#: Аргументами операции являются:&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M1 = (F_{x_{o_p}}^{It}; x_{o_p})&amp;lt;/math&amp;gt; - результаты срабатывания операций, соответствующих вершинам из шестой группы с координатами &amp;lt;math&amp;gt;It, i,&amp;lt;/math&amp;gt; всего &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; величин;&lt;br /&gt;
#:* &amp;lt;math&amp;gt;M2_{It-1}:&amp;lt;/math&amp;gt;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It = 1&amp;lt;/math&amp;gt; - результат выполнения фазы BUILD;&lt;br /&gt;
#:** при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt; - результаты срабатывания операции, соответствующей вершине из седьмой группы с координатой &amp;lt;math&amp;gt;It-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
#: Результат срабатывания операции является:&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It &amp;lt; T&amp;lt;/math&amp;gt; - &#039;&#039;промежуточным данным&#039;&#039; алгоритма;&lt;br /&gt;
#:* при &amp;lt;math&amp;gt;It = T&amp;lt;/math&amp;gt; - &#039;&#039;выходным данным&#039;&#039; фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Описанный граф в общем случае представлен на Рис.3, отображена одна итерация фазы SWAP.&lt;br /&gt;
Обозначения:&lt;br /&gt;
# вершины первой группы обозначены фиолетовым цветом и подписаны как &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины второй группы обозначены синим цветом и подписаны как &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины третьей группы обозначены желтым цветом и подписаны как &amp;lt;math&amp;gt;\overline{a}_{x_{m_i} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины четвертой группы обозначены оранжевым цветом и подписаны как &amp;lt;math&amp;gt;\overline{b}_{x_{m_i o_p} };&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины пятой группы обозначены серым цветом и подписаны как &amp;lt;math&amp;gt;S;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины шестой группы обозначены зеленым цветом и подписаны как &amp;lt;math&amp;gt;M1;&amp;lt;/math&amp;gt;&lt;br /&gt;
# вершины седьмой группы обозначены красным цветом и подписаны как &amp;lt;math&amp;gt;M2;&amp;lt;/math&amp;gt;&lt;br /&gt;
# синим дугам сопоставлены метки, отражающие данные, используемые в соответствующих оранжевых вершинах;&lt;br /&gt;
# фиолетовым дугам сопоставлены метки, отражающие данные, используемые в соответствующих жёлтых вершинах.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Pam swap 1.png|thumb|center|1100px|Рисунок 3. Граф фазы SWAP алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На Рис.4 представлен граф фазы SWAP для случая &amp;lt;math&amp;gt;n=6, k=2, T=3.&amp;lt;/math&amp;gt; Вершины, соответствующие операциям, получающим входные данные и производящим выходные данные, увеличены и выделены толстыми границами.&lt;br /&gt;
&lt;br /&gt;
[[file:Pam swap 2.png|thumb|center|1100px|Рисунок 4. Граф фазы SWAP алгоритма для n = 6, k = 2, T = 3.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
При параллельной реализации алгоритма PAM будем рассматривать параллельные варианты фазы BUILD и SWAP ([[#Возможная параллельная реализация алгоритма PAM|возможная параллельная реализация]]). Покажем, что сложность фазы BUILD сопоставима со сложностью одной итерации фазы SWAP.&lt;br /&gt;
&lt;br /&gt;
Оценки последовательной сложности фаз BUILD и SWAP приведены в параграфе &amp;quot;[[#Последовательная сложность алгоритма|Последовательная сложность алгоритма]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Ресурс параллелизма фазы BUILD ====&lt;br /&gt;
&lt;br /&gt;
Для решения задачи кластеризации методом PAM в параллельном варианте фазы BUILD в предположении доступности неограниченного числа процессов для одной итерации необходимо выполнить:&lt;br /&gt;
*  1 ярус с нахождением &amp;lt;math&amp;gt;\overline{c}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It &amp;gt; 1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* 1 ярус с нахождением суммы &amp;lt;math&amp;gt;S:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операцию сложения;&lt;br /&gt;
* 1 ярус с нахождением значений элемента &amp;lt;math&amp;gt;M1:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &amp;lt;math&amp;gt;\overline{MIN}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It&amp;gt;1;&amp;lt;/math&amp;gt;&lt;br /&gt;
* 1 ярус с изменением множеств медоидов и не-медоидов (не выполняются операции рассматриваемых типов).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность одного шага фазы BUILD равна: &lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операция сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It=1;&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n-It&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов при &amp;lt;math&amp;gt;It&amp;gt;1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность фазы BUILD при числе кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; равна: &lt;br /&gt;
* &amp;lt;math&amp;gt;kn-k&amp;lt;/math&amp;gt; операция сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;3kn - 2n - \frac{1}{2}k^2 - \frac{1}{2}k&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, по сравнению с последовательным, при &amp;lt;math&amp;gt;k, n \to \infty&amp;lt;/math&amp;gt; количество операций на один порядок меньше по параметру &amp;lt;math&amp;gt;n:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt; против &amp;lt;math&amp;gt;O(kn^2).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соотношение количества сложений и взятий минимума для фазы BUILD является постоянным и стремится к &amp;lt;math&amp;gt;3,&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;k, n \to \infty.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Максимальная ширина яруса достигается при вычислении &amp;lt;math&amp;gt;\overline {c}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; и равна &amp;lt;math&amp;gt;n-It+1&amp;lt;/math&amp;gt; для шага &amp;lt;math&amp;gt;It&amp;lt;/math&amp;gt; фазы BUILD. Максимальная ширина яруса при рассмотрении всей фазы есть &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и достигается на первом шаге.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Ресурс параллелизма фазы SWAP ====&lt;br /&gt;
&lt;br /&gt;
Для решения задачи кластеризации методом PAM в параллельном варианте фазы SWAP в предположении доступности неограниченного числа процессов для одной итерации необходимо выполнить:&lt;br /&gt;
* 1 ярус с нахождением &amp;lt;math&amp;gt;\overline {a}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n(k-1)&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением &amp;lt;math&amp;gt;\overline {b}:&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операций нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением суммы &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;:&lt;br /&gt;
** &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операцию сложения;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &#039;первого&#039; вида &amp;lt;math&amp;gt;(M1 = \min_{x_{o_p} \in O} S):&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;n-k-1&amp;lt;/math&amp;gt; операцию нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с нахождением минимального элемента &#039;второго&#039; вида &amp;lt;math&amp;gt;(M2 = \min_{x_{m_i} \in M} M1):&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt; операцию нахождения минимального из двух элементов;&lt;br /&gt;
* 1 ярус с изменением множеств медоидов и не-медоидов (не выполняются операции рассматриваемых типов).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельная сложность одной итерации фазы SWAP равна:&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - по количеству операций сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;kn + n - 2&amp;lt;/math&amp;gt; - по количеству операций нахождений минимума для двух чисел.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В параллельном варианте, по сравнению с последовательным, при &amp;lt;math&amp;gt;k, n \to \infty&amp;lt;/math&amp;gt; количество операций на один порядок меньше по параметру &amp;lt;math&amp;gt;n:&amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt; против &amp;lt;math&amp;gt;O(kn^2).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соотношение количества сложений и взятий минимума для одной итерации фазы SWAP является постоянным и равным &amp;lt;math&amp;gt;k,&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;n \to \infty&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Максимальная ширина яруса достигается при вычислении &amp;lt;math&amp;gt;\overline {b}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; и равна &amp;lt;math&amp;gt;k(n-k).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При использовании выбранной модели, в предположении доступности неограниченного числа вычислителей, фаза BUILD при &amp;lt;math&amp;gt;n \to \infty&amp;lt;/math&amp;gt; требует большего количества операций суммирования на порядок &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, по сравнению с одной итерацией фазы SWAP. В свою очередь, количество операций подсчёта минимума ассимптотически эквивалентны.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные&#039;&#039;:&lt;br /&gt;
* число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество точек упорядоченного множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
* число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество требуемых кластеров;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов, состоящих из &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; вещественных чисел, - попарных расстояний между элементами из множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; за исключением расстояний вида &amp;lt;math&amp;gt;\rho (x, x)=0, x \in X;&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;Объём входных данных&#039;&#039;: &amp;lt;math&amp;gt;n(n-1)&amp;lt;/math&amp;gt; вещественное число и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; целых числа.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Структура хранения данных&#039;&#039;:&lt;br /&gt;
* сразу после считывания входных данных составляется квадратная симметрическая матрица &amp;lt;math&amp;gt;D^{n * n}&amp;lt;/math&amp;gt;, у которой каждый элемент &amp;lt;math&amp;gt;d_{ij}&amp;lt;/math&amp;gt; является вещественным числом - расстоянием &amp;lt;math&amp;gt;\rho (x_i, x_j);&amp;lt;/math&amp;gt;&lt;br /&gt;
* для множества медоидов &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; создаётся массив из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; целых чисел - индексов принадлежащих ему элементов из множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, аналогичный массив &amp;lt;math&amp;gt;n-k&amp;lt;/math&amp;gt; целых чисел создаётся для множества не-медоидов &amp;lt;math&amp;gt;O;&amp;lt;/math&amp;gt;&lt;br /&gt;
* для пересылки данных, как правило, используется тройка &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}; x_{m_s}; x_{o_h})&amp;lt;/math&amp;gt; или пара &amp;lt;math&amp;gt;(F_{x_{o_h}}^{i_j}; x_{o_h}),&amp;lt;/math&amp;gt; где:&lt;br /&gt;
** &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; - целое число, обозначающее порядковый номер элемента множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; - целое число, обозначающее порядковый номер элемента множества &amp;lt;math&amp;gt;X;&amp;lt;/math&amp;gt;&lt;br /&gt;
** &amp;lt;math&amp;gt;F_{x_{m_s}, x_{o_h}}^{i_j}&amp;lt;/math&amp;gt; - вещественное число, равное минимальному значению целевой функции, вычисленному в текущем контексте.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Выходные данные&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; целых чисел, составляющих множество &amp;lt;math&amp;gt;M;&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; вещественное число, являющееся значением целевой функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Объём выходных данных&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;  целых чисел и &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;  вещественное.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности алгоритма является &#039;&#039;линейным&#039;&#039; и равным &amp;lt;math&amp;gt;n.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Вычислительная мощность&#039;&#039; последовательного алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, равна &amp;lt;math&amp;gt;O(T*k).&amp;lt;/math&amp;gt;&lt;br /&gt;
Вычислительная мощность параллельного алгоритма равна &amp;lt;math&amp;gt;O(T*\frac{k}{n}).&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм PAM является &#039;&#039;менее чувствительным&#039;&#039; к выбросам данных, чем алгоритм k-средних. Это связано с использованием медоидов, менее подверженных влиянию таких данных.&amp;lt;ref&amp;gt; Егоров А. В., Куприянова Н. И. Особенности методов кластеризации данных // Известия Южного федерального университета. Технические науки. –2011. T. 124, № 11. –С. 174-177.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Фиксированный способ выбора начальных приближений позволяет говорить о воспроизводимости полученных результатов для последовательной реализации, однако для параллельной работы алгоритма имеет место быть лишь воспроизводимость итогового значения целевой функции. Из-за &#039;&#039;недетерминированности&#039;&#039; выбора элементов, на которых достигается минимальное значение целевой функции на каждой итерации, итоговое множество медоидов может меняться.&lt;br /&gt;
&lt;br /&gt;
Алгоритм PAM &#039;&#039;конечен&#039;&#039;, так как:&lt;br /&gt;
* количество операций фазы BUILD конечно;&lt;br /&gt;
* значение целевой фукнции неотрицательно и на каждой итерации фазы SWAP строго уменьшается.&lt;br /&gt;
&lt;br /&gt;
Одно из преимуществ алгоритма PAM заключается в том, что он может работать с любой матрицей различий. В данном случае принципиальное отличие от матрицы расстояний заключается в том, что для матрицы различий может не выполняться неравенство треугольника, так как в основе её построения не обязательно используется метрика.&lt;br /&gt;
&lt;br /&gt;
Основные операция алгоритма PAM: сложение и нахождение минимума. Операция взятия минимума не подвержена процессу накопления ошибки. На каждой итерации алгоритма сложение производится над значениями, взятыми непосредственно из исходных данных. Таким образом, алгоритм PAM не накапливает ошибок в процессе своей работы и является &#039;&#039;устойчивым&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;math&amp;gt;k(n-k) \, \bmod \, p \neq 0&amp;lt;/math&amp;gt; отсутствует возможность равномерно распределить задачи рассчёта &amp;lt;math&amp;gt;\overline{b}&amp;lt;/math&amp;gt; между процессами. Кроме того, если &amp;lt;math&amp;gt;k \, \bmod \, p \neq 0&amp;lt;/math&amp;gt;, то после их распределения для некоторых процессов окажется необходимым вычислить несколько соседних значений &amp;lt;math&amp;gt;\overline{a}.&amp;lt;/math&amp;gt; Таким образом, &#039;&#039;равномерная&#039;&#039; загрузка процессов &#039;&#039;не всегда возможна&#039;&#039;. Помимо этого, агрегирование данных с целью вычисления глобального минимума приводит к простою незадействованных процессов.&lt;br /&gt;
&lt;br /&gt;
Как и большинство алгоритмов кластеризации, PAM может сходиться к некоторому &#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;
==== Возможная параллельная реализация алгоритма PAM ====&lt;br /&gt;
&lt;br /&gt;
Необходимость уменьшения времени решения задачи приводит к потребности в создании паралельной реализации алгоритма. В дальнейшем будем придерживаться следующих допущений:&lt;br /&gt;
* возможно использование &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов;&lt;br /&gt;
* не нарушая общности суждений, множества &amp;lt;math&amp;gt;M, O&amp;lt;/math&amp;gt; - упорядоченны.&lt;br /&gt;
&lt;br /&gt;
Приведённые далее возможные схемы для параллельных реализаций фазы BUILD и фазы SWAP основаны на максимально равномерном распределении задач между процессами.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Возможная параллельная реализация фазы BUILD =====&lt;br /&gt;
&lt;br /&gt;
Главная задача заключается в распараллеливании множественного вычисления целевой функции на каждой итерации фазы BUILD:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{o_h} \in O_{i-1}} F_{x_{o_h}}^i,&amp;lt;/math&amp;gt; где &amp;lt;math&amp;gt;F_{x_{o_h}}^i = \sum_{j = 1}^{n} \overline{MIN}_{i, x_{o_h}}^{(j)},&amp;lt;/math&amp;gt; где&lt;br /&gt;
: &amp;lt;math&amp;gt;\overline{MIN}_{1, x_{o_h} \in O_0} = \{ \rho (x_{o_h}, x_j ) \| 1 \leq j \leq n \};&amp;lt;/math&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{o_h} \in O_{i-1}} = \{ \min ( \overline{MIN}_{i-1, x_{m_{i-1}}}^{(j)}, \rho (x_{o_h}, x_j) ) \| 1 \leq j \leq n \}, \forall i: 1 &amp;lt; i \leq k.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Схема реализации&#039;&#039;: &amp;lt;br&amp;gt;(далее &amp;lt;math&amp;gt;0 &amp;lt; i \leq k &amp;lt;/math&amp;gt; - номер текущей итерации)&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## положим:&lt;br /&gt;
##: &amp;lt;math&amp;gt;pos = p-(n-i+1) \, \bmod \, p;&amp;lt;/math&amp;gt;&lt;br /&gt;
## на каждой итерации процессу необходимо вычислить &amp;lt;math&amp;gt;r_j&amp;lt;/math&amp;gt; значений целевой функции для соответствующих ему элементов &amp;lt;math&amp;gt;x_{o_h}, ..., x_{o_{h+(r_j-1)}}:&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt; r_j = \begin{cases}&lt;br /&gt;
    \lfloor \frac{n-i+1}{p} \rfloor , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    \lceil \frac{n-i+1}{p} \rceil , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;h = \begin{cases}&lt;br /&gt;
    r_j*j , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    (r_j-1)*pos + (j-pos)*r_j , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# каждому процессу с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## найти минимум среди значений целевой функции &amp;lt;math&amp;gt;F_{x_{o_h}}^i&amp;lt;/math&amp;gt; для каждого из значений параметра &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt; &lt;br /&gt;
##* в данном случае может быть использована оптимизация, описанная в [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]];&lt;br /&gt;
## для процессов с номером &amp;lt;math&amp;gt;j \neq 0&amp;lt;/math&amp;gt; переслать процессу с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt; пару &amp;lt;math&amp;gt;(x_{o_h}, F_{x_{o_h}}^i)&amp;lt;/math&amp;gt; для всех обработанных &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# для процесса с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;:&lt;br /&gt;
## принять пары от процессов &amp;lt;math&amp;gt;(0, p-1],&amp;lt;/math&amp;gt; в ответ на шаг 2.2;&lt;br /&gt;
## найти &amp;lt;math&amp;gt;x_{o_h},&amp;lt;/math&amp;gt; для которого целевая функция принимает минимальное значение, и положить &amp;lt;math&amp;gt;x_{m_i}:=x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
## вычислить &amp;lt;math&amp;gt;\overline{MIN}_{i, x_{m_i}}&amp;lt;/math&amp;gt;;&lt;br /&gt;
## разослать пару &amp;lt;math&amp;gt;(x_{m_i}, \overline{MIN}_{i, x_{m_i}})&amp;lt;/math&amp;gt; при помощи широковещательной рассылки;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять пару &amp;lt;math&amp;gt;(x_{m_i}, \overline{MIN}_{i, x_{m_i}})&amp;lt;/math&amp;gt; в ответ на шаг 3.4;&lt;br /&gt;
## скорректировать локальные копии множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt;, изменив принадлежность вектора &amp;lt;math&amp;gt;x_{m_i}&amp;lt;/math&amp;gt;, а также обновить хранимое значение вектора &amp;lt;math&amp;gt;\overline{MIN}&amp;lt;/math&amp;gt; для подготовки к следующей итерации;&lt;br /&gt;
## перейти к шагу 2.1.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
После завершения &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; шагов фазы BUILD, множества &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt; (одинаковые для каждого процесса согласно приведенной схеме), а так же значение целевой функции являются выходными данными фазы BUILD.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Возможная параллельная реализация фазы SWAP =====&lt;br /&gt;
&lt;br /&gt;
Главная задача заключается в распараллеливании многократного вычисления целевой функции на каждой итерации фазы SWAP:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;F^i = \min_{x_{m_s} \in M_{i-1} } \min_{x_{o_h} \in O_{i-1}} \sum_{j = 1}^{n} \min ( \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )) , \rho ( x_{o_h},x_j) )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Схема реализации&#039;&#039;: &amp;lt;br&amp;gt;(далее &amp;lt;math&amp;gt;i \in \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;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## положим:&lt;br /&gt;
##: &amp;lt;math&amp;gt;pos = p-(k*(n-k)) \, \bmod \, p;&amp;lt;/math&amp;gt;&lt;br /&gt;
## на каждой итерации процессу необходимо вычислить &amp;lt;math&amp;gt;r_j&amp;lt;/math&amp;gt; значений целевой функции для соответствующих ему пар вида (медоид, не-медоид)   &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h}), (x_{m_s}, x_{o_{h+1}}), ..., (x_{m_s}, x_{o_{n-k}}), (x_{m_{s+1}}, x_{o_0}), (x_{m_{s+1}}, x_{o_1}), . . . \, : &amp;lt;/math&amp;gt;&lt;br /&gt;
##:&amp;lt;math&amp;gt; r_j =   \begin{cases}&lt;br /&gt;
    \lfloor \frac{k*(n-k)}{p} \rfloor , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
    \lceil \frac{k*(n-k)}{p} \rceil , pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;s = \begin{cases}&lt;br /&gt;
    (r_j*j) \mbox{ div } (n-k) , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
     ((r_j-1)*pos + r_j*(j-pos)) \mbox{ div } (n-k), pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{m_s};&amp;lt;/math&amp;gt;&lt;br /&gt;
##: &amp;lt;math&amp;gt;h = \begin{cases}&lt;br /&gt;
    (r_j*j) \, \bmod \,  (n-k) , 0 \leq j &amp;lt; pos &amp;amp; \quad\\&lt;br /&gt;
     ((r_j-1)*pos + r_j*(j-pos)) \, \bmod \,  (n-k), pos  \leq j &amp;amp; \quad\\&lt;br /&gt;
  \end{cases}&amp;lt;/math&amp;gt; - порядковый номер &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# каждому процессу с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## найти минимум среди вычисленных значений целевой функции для каждого из значений первого параметра &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; по соответствующим ему &amp;lt;math&amp;gt;x_{o_h};&amp;lt;/math&amp;gt;&lt;br /&gt;
##* в данном случае может быть использована оптимизация, описанная в [[#Вычислительное ядро алгоритма|вычислительном ядре алгоритма]];&lt;br /&gt;
## переслать процессу с номером &amp;lt;math&amp;gt;N = s \, \bmod \, p&amp;lt;/math&amp;gt; (если &amp;lt;math&amp;gt;N \neq j&amp;lt;/math&amp;gt;) тройку &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}, x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; для всех обработанных &amp;lt;math&amp;gt;x_{m_s};&amp;lt;/math&amp;gt;&lt;br /&gt;
# для процессов с номерами &amp;lt;math&amp;gt;j&amp;lt;\min (p, k):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять описанные выше тройки от процессов, обработавших элементы &amp;lt;math&amp;gt;x_{m_{z \, \bmod \, p = j}}, z = \overline {0, k-1},&amp;lt;/math&amp;gt; в ответ на шаг 2.2;&lt;br /&gt;
## вычислить минимальное среди полученных значений целевой функции;&lt;br /&gt;
## запомнить &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt;, на которых минимальное значение было достигнуто;&lt;br /&gt;
## при &amp;lt;math&amp;gt;j \neq 0 &amp;lt;/math&amp;gt; отправить тройку &amp;lt;math&amp;gt;(F_{x_{m_s}, x_{o_h}}^{i_j}, x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, соответствующую выбранной паре, процессу с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
# для процесса с номером &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;:&lt;br /&gt;
## принять тройки от процессов &amp;lt;math&amp;gt;(0, min(k-1, p-1)],&amp;lt;/math&amp;gt; в ответ на шаг 3.4;&lt;br /&gt;
## найти пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, для которой целевая функция принимает минимальное значение;&lt;br /&gt;
## сравнить найденное минимальное значение с вычисленным значением целевой функции на предыдущей итерации фазы SWAP;&lt;br /&gt;
### (&#039;&#039; &#039;&#039;&#039;условие останова&#039;&#039;&#039; &#039;&#039;) если значение целевой функции не уменьшилось, остановить вычисление;&lt;br /&gt;
### иначе, разослать выявленную пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; при помощи широковещательной рассылки;&lt;br /&gt;
# для каждого процесса с номером &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;(0 \leq j &amp;lt; p):&amp;lt;/math&amp;gt;&lt;br /&gt;
## принять пару &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; в ответ на шаг 4.3.2;&lt;br /&gt;
## скорректировать локальные копии множеств &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt;, заменяя элемент &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt; на элемент &amp;lt;math&amp;gt;x_{o_h}&amp;lt;/math&amp;gt; и наоборот;&lt;br /&gt;
## перейти к шагу 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Ограничения и недостатки =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Ограничения&#039;&#039;:&lt;br /&gt;
* предполагается, что матрица расстояний &amp;lt;math&amp;gt;D^{n * n}&amp;lt;/math&amp;gt; полностью помещается в памяти каждого процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Недостатки&#039;&#039;:&lt;br /&gt;
* при распределении обсчитываемых целевых функций, каждому из процессов ставится в соответствие некоторая совокупность пар &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt;, для которых нужно рассчитать значения целевой функции. В случае, если количество процессов не кратно количеству обрабатываемых кластеров, различные процессы получат пары у которых совпадают &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt;, что приведёт к совершению одинаковых вычислений на различных процессах: &amp;lt;math&amp;gt;   \min_{ x_{m_l} \in M_{i-1} \backslash \{x_{m_s}\} } ( \rho ( x_{m_l},x_j )), 1 \leq j \leq n;&amp;lt;/math&amp;gt;&lt;br /&gt;
* вычисление фазы SWAP успешно распараллеливается между &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессами, однако после этого происходит агрегация данных в 2 этапа относительно &amp;lt;math&amp;gt;(x_{m_s}, x_{o_h})&amp;lt;/math&amp;gt; для вычисления глобального минимума. На первом этапе данные собираются на первых &amp;lt;math&amp;gt;\min (p,k)&amp;lt;/math&amp;gt; процессах, где происходят локальные вычисления минимумов среди принятых данных (для каждого &amp;lt;math&amp;gt;x_{m_s}&amp;lt;/math&amp;gt;), после чего полученные минимумы и связанная с ними информация агрегируются на мастер-процессе, который вычисляет глобальный минимум и извещает о нём все остальные процессы. &amp;lt;br&amp;gt;Во время описанных вычислений все незадействованные процессы простаивают.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Дополнительные возможности&#039;&#039;:&lt;br /&gt;
* помимо описанной схемы, также есть возможность распараллелить операцию вычисления матрицы расстояний &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;, однако это является отдельной алгоритмической задачей и не даёт существенного прироста производительности алгоритма.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Существующие параллельные реализации алгоритма PAM ====&lt;br /&gt;
&lt;br /&gt;
Примером другой параллельной реализации алгоритма PAM может служить реализация в пакете SPRINT для языка R (подробнее см. [[#Существующие реализации алгоритма|существующие реализации алгоритма]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Срок сдачи продлён до 15-го ноября.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# Последовательная реализация алгоритма PAM в пакете ClusterR на языке R:&lt;br /&gt;
#* Лицензия: MIT&lt;br /&gt;
#* [https://cran.r-project.org/package=ClusterR веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в функции &#039;Cluster_Medoids&#039;. Отличительная особенность реализации &amp;lt;ref&amp;gt;Lampros Mouselimis [https://cran.r-project.org/web/packages/cluster/cluster.pdf Package &#039;ClusterR&#039;]. October 8, 2016&amp;lt;/ref&amp;gt;:&lt;br /&gt;
#** для задания метрики между элементами кластеризуемого множества передаётся строка, задающая одну из реализованных в алгоритме метрик. Данный подход теряет одно из преимуществ алгоритма PAM, позволяющее в качестве матрицы расстояний использовать произвольную матрицу различий.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Последовательная реализация алгоритма PAM в пакете Cluster на языке R:&lt;br /&gt;
#* Лицензия: GPL (≥2)&lt;br /&gt;
#* [https://cran.r-project.org/package=cluster веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в функции &#039;pam()&#039;. Данная реализация имеет следующие особенности &amp;lt;ref&amp;gt;Martin Maechler., etc. [https://cran.r-project.org/web/packages/cluster/cluster.pdf Package &#039;cluster&#039;]. October 8, 2016&amp;lt;/ref&amp;gt;:&lt;br /&gt;
#** функция может принимать на вход не множество точек, а матрицу расстояний между ними;&lt;br /&gt;
#** реализация более гибкая, так как принимает на вход матрицу различий элементов, а не использует какую-либо метрику;&lt;br /&gt;
#** может быть предоставлено графическое отображение.&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Параллельная реализация алгоритма PAM в пакете SPRINT (Simple Parallel R INTerface - параллельный фреймворк) на языке R:&lt;br /&gt;
#* Лицензия: GPL (≥3)&lt;br /&gt;
#* [https://cran.r-project.org/package=sprint веб-страница фреймворка (исходный код, системные требования и справочное руководство)]&lt;br /&gt;
#* Алгоритм PAM реализован в фукции &#039;ppam()&#039;. Входные параметры данной функции схожи с параметрами, задаваемыми в линейной реализации &#039;pam()&#039; пакета Cluster языка R. Отличительной особенностью является подача на вход предвычисленной матрицы расстояний (например, с помощью функции &#039;pcor()&#039; из этой же библиотеки).&amp;lt;ref&amp;gt;University of Edinburgh SPRINT Team. [https://cran.r-project.org/web/packages/sprint/sprint.pdf Package &#039;sprint&#039;]. February 20, 2015&amp;lt;/ref&amp;gt;&lt;br /&gt;
#:&lt;br /&gt;
#:&lt;br /&gt;
# Параллельная реализация алгоритма PAM на основе операций MapReduce на Hadoop кластере.&lt;br /&gt;
#* В рамках исследования по ускорению анализа информации о геноме были созданы реализации алгоритма PAM с использованием технологии MPI и технологии MapReduce. Реализация в открытом досупе отсутствует. &amp;lt;ref&amp;gt;[Dobrzelecki B. et al. Managing and analysing Genomic Data using HPC and Clouds //Grid and Cloud Database Management. – Springer Berlin Heidelberg, 2011. – С. 261-277.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
MKL, ScaLAPACK, PETSc, FFTW, ATLAS, Magma и другие подобные библиотеки.&lt;br /&gt;
&lt;br /&gt;
* Дать ссылки на существующие последовательные и параллельные реализации алгоритма (&amp;quot;уже доступные&amp;quot;)&lt;br /&gt;
* Реализация - коммерческая/свободная, лицензия&lt;br /&gt;
* ссылка на дистрибутив и описание&lt;br /&gt;
* особенности, достоинства/недостатки, ....&lt;br /&gt;
&lt;br /&gt;
гугл-запрос: &amp;quot;partitioning around medoids&amp;quot; &amp;quot;PAM&amp;quot; BUILD SWAP &amp;quot;MPI&amp;quot; &amp;quot;program&amp;quot; &amp;quot;package&amp;quot; -worldwidescience&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Anastasia</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:Anastasia&amp;diff=4039</id>
		<title>Участник:Anastasia</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:Anastasia&amp;diff=4039"/>
		<updated>2016-09-14T12:21:41Z</updated>

		<summary type="html">&lt;p&gt;Anastasia: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Graduated bachelor&lt;br /&gt;
&lt;br /&gt;
Lomonosov Moscow State University&lt;br /&gt;
&lt;br /&gt;
Faculty of Computational Mathematics and Cybernetics&lt;/div&gt;</summary>
		<author><name>Anastasia</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:Anastasia&amp;diff=4037</id>
		<title>Участник:Anastasia</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:Anastasia&amp;diff=4037"/>
		<updated>2016-09-14T11:18:00Z</updated>

		<summary type="html">&lt;p&gt;Anastasia: Новая страница: «Graduated bachelor  Lomonosov Moscow State University  Faculty of Computional Mathematics and Cybernetics»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Graduated bachelor&lt;br /&gt;
&lt;br /&gt;
Lomonosov Moscow State University&lt;br /&gt;
&lt;br /&gt;
Faculty of Computional Mathematics and Cybernetics&lt;/div&gt;</summary>
		<author><name>Anastasia</name></author>
	</entry>
</feed>