<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Joshik</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Joshik"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%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/Joshik"/>
		<updated>2026-05-19T18:00:48Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26131</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26131"/>
				<updated>2012-06-20T12:23:00Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in \mathbb{R}^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = \{x^1, x^2, ..., x^n\} \subset \mathbb{R}^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | x \succ y\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\mu&amp;lt;/tex&amp;gt; - мера Лебега.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперпараллелепипедов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперпараллелепипедов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперпараллелепипеды.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперпараллелепипедов, и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure&amp;lt;ref&amp;gt;Bringmann K., Friedrich. T.: An Efficient Algorithm for Computing Hypervolume Contributions. Evolutionary Computation, Vol. 18, No. 3, MIT Press, pp 383-402. (2010)&amp;lt;/ref&amp;gt; обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперпараллелепипеда, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировавшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует параллелепипед с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого параллелепипеда к ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;. При этом точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритма напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются именно в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в &amp;lt;ref name = &amp;quot;while&amp;quot;/&amp;gt;. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и эта зависимость близка к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; &amp;lt;ref name=&amp;quot;while&amp;quot;&amp;gt;&lt;br /&gt;
While, L., Hingston, P., Barone, L., Huband, S.: A Faster Algorithm for Calculating Hypervolume. IEEE Transaction on Evolutionary Computation, Vol.10, No. 1, pp 29–38. (2006)&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;\mathbb{R}^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO&amp;lt;ref&amp;gt;Zhou X., Sun C., Mao N., Li W.: Generalization of HSO algortihms for computing hypervolume for mutiobjective optimization problems, IEEE Congress on Evolutionary Computation. (2007)&amp;lt;/ref&amp;gt; рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения'' (разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' (гиперплоскости), проходящего перпендикулярно оси первой координаты, не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза, и умножить на длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все исходные &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, вторая - все, помимо точки с минимальной первой координатой, вдоль которой происходит расслоение, и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперпараллелепипедов и остается их найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперпараллелепипеда, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База:&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем полезные леммы:&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}^{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Переход: предполагаем, что утверждение верно для &amp;lt;tex&amp;gt;r = j&amp;lt;/tex&amp;gt;. Раскрываем первое слагаемое в правой части предположения аналогично базе и получаем: &lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - j - 1 \choose y} + {x - (j + 1) \choose y - 1} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1} = {x - (j + 1) \choose y} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Подставляем в предыдущую лемму &amp;lt;tex&amp;gt;r = x - y&amp;lt;/tex&amp;gt; и получаем:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {y \choose y} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = {x - (x - y + 1) \choose y - 1} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
продолжаем доказательство теоремы по индукции:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1} = \sum \limits_{i = 1}^{n} {n + d - 2 - i \choose d - 2} = \sum \limits_{k = n}^{1} {n + d + 2 - (n - k + 1) \choose d - 2} = \sum \limits_{k = 1}^{n} {k + d - 3 \choose d - 2} = \sum \limits_{k = 1}^{n}{k + (d - 1) - 2 \choose (d - 1) - 1} = \sum \limits_{k = 1}^{n}{f(k, d - 1)}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике &amp;lt;ref name =&amp;quot;while&amp;quot;/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперпараллелепипед с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP&amp;lt;ref name = &amp;quot;overmars&amp;quot;&amp;gt;Overmars M.H., Yap C.K.: New upper bounds in Klee’s measure problem. SIAM Journal on Computing 20(6), pp 1034–1045. (1991)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Beume N.: S-Metric calculation by considering dominated hypervolume as Klee’s measure problem. Evolutionary Computation, 17(4), pp 477–492. (2009)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Beume N., Rudolph G.: Faster S-metric calculation by considering dominated hypervolume as Klee’s measure problem. In Proc. Second International Conference on Computational Intelligence (IASTED ’06), pp 233–238. (2006)&amp;lt;/ref&amp;gt;, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперпараллелепипедов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперпараллелепипедов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
В трехмерном пространстве сканирующая гиперплоскость превращается в обычную плоскость. Будем считать, что она всегда располагается перпендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; и двигается от минимальных значений по этой оси до максимальных. В каждый момент проекция всех параллелепипедов на эту плоскость представляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всей области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перпендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиеся &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе, возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой вертикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину дерева. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перпендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитываем площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат, получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все идеи этого алгоритма обобщаются с трехмерного пространства на &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерное следующим образом.&lt;br /&gt;
&lt;br /&gt;
Построение разбиения на области в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;), а также каждую &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.&lt;br /&gt;
&lt;br /&gt;
Это разбиение на области имеет следующие аналогичные свойства:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый гиперпараллелепипед частично покрывает не более &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Общее дерево строится аналогичным образом и оно в итоге состоит из &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уровней, каждый из которых имеет высоту &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый гиперпараллелепипед хранится в &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый гиперпараллелепипед влияет на &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности &amp;lt;tex&amp;gt;d-1&amp;lt;/tex&amp;gt;, в котором необходимо провести &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; операций, то есть суммарное время работы алгоритма равно: &amp;lt;tex&amp;gt;O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)&amp;lt;/tex&amp;gt;. При этом хранение КД-дерева требует &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26122</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26122"/>
				<updated>2012-06-20T12:07:05Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in \mathbb{R}^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = \{x^1, x^2, ..., x^n\} \subset \mathbb{R}^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | x \succ y\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\mu&amp;lt;/tex&amp;gt; - мера Лебега.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов, и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure&amp;lt;ref&amp;gt;Bringmann K., Friedrich. T.: An Efficient Algorithm for Computing Hypervolume Contributions. Evolutionary Computation, Vol. 18, No. 3, MIT Press, pp 383-402. (2010)&amp;lt;/ref&amp;gt; обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировавшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба к ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;. При этом точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритма напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются именно в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в &amp;lt;ref name = &amp;quot;while&amp;quot;/&amp;gt;. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и эта зависимость близка к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; &amp;lt;ref name=&amp;quot;while&amp;quot;&amp;gt;&lt;br /&gt;
While, L., Hingston, P., Barone, L., Huband, S.: A Faster Algorithm for Calculating Hypervolume. IEEE Transaction on Evolutionary Computation, Vol.10, No. 1, pp 29–38 (2006)&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;\mathbb{R}^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO&amp;lt;ref&amp;gt;Zhou X., Sun C., Mao N., Li W.: Generalization of HSO algortihms for computing hypervolume for mutiobjective optimization problems, IEEE Congress on Evolutionary Computation. (2007)&amp;lt;/ref&amp;gt; рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения'' (разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' (гиперплоскости), проходящего перпендикулярно оси первой координаты, не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза, и умножить на длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все исходные &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, вторая - все, помимо точки с минимальной первой координатой, вдоль которой происходит расслоение, и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается их найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База:&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем полезные леммы:&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}^{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Переход: предполагаем, что утверждение верно для &amp;lt;tex&amp;gt;r = j&amp;lt;/tex&amp;gt;. Раскрываем первое слагаемое в правой части предположения аналогично базе и получаем: &lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - j - 1 \choose y} + {x - (j + 1) \choose y - 1} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1} = {x - (j + 1) \choose y} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Подставляем в предыдущую лемму &amp;lt;tex&amp;gt;r = x - y&amp;lt;/tex&amp;gt; и получаем:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {y \choose y} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = {x - (x - y + 1) \choose y - 1} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
продолжаем доказательство теоремы по индукции:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1} = \sum \limits_{i = 1}^{n} {n + d - 2 - i \choose d - 2} = \sum \limits_{k = n}^{1} {n + d + 2 - (n - k + 1) \choose d - 2} = \sum \limits_{k = 1}^{n} {k + d - 3 \choose d - 2} = \sum \limits_{k = 1}^{n}{k + (d - 1) - 2 \choose (d - 1) - 1} = \sum \limits_{k = 1}^{n}{f(k, d - 1)}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике &amp;lt;ref name =&amp;quot;while&amp;quot;/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP&amp;lt;ref name = &amp;quot;overmars&amp;quot;&amp;gt;Overmars M.H., Yap C.K.: New upper bounds in Klee’s measure problem. SIAM Journal on Computing 20(6), pp 1034–1045. (1991)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Beume N.: S-Metric calculation by considering dominated hypervolume as Klee’s measure problem. Evolutionary Computation, 17(4), pp 477–492. (2009)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Beume N., Rudolph G.: Faster S-metric calculation by considering dominated hypervolume as Klee’s measure problem. In Proc. Second International Conference on Computational Intelligence (IASTED ’06), pp 233–238. (2006)&amp;lt;/ref&amp;gt;, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
В трехмерном пространстве сканирующая гиперплоскость превращается в обычную плоскость. Будем считать, что она всегда располагается перпендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; и двигается от минимальных значений по этой оси до максимальных. В каждый момент проекция всех параллелепипедов на эту плоскость представляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всей области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перпендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиеся &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе, возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой вертикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину дерева. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перпендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитываем площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат, получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все идеи этого алгоритма обобщаются с трехмерного пространства на &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерное следующим образом.&lt;br /&gt;
&lt;br /&gt;
Построение разбиения на области в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;), а также каждую &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.&lt;br /&gt;
&lt;br /&gt;
Это разбиение на области имеет следующие аналогичные свойства:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый гиперпараллелепипед частично покрывает не более &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Общее дерево строится аналогичным образом и оно в итоге состоит из &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уровней, каждый из которых имеет высоту &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый гиперпараллелепипед хранится в &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый гиперпараллелепипед влияет на &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности &amp;lt;tex&amp;gt;d-1&amp;lt;/tex&amp;gt;, в котором необходимо провести &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; операций, то есть суммарное время работы алгоритма равно: &amp;lt;tex&amp;gt;O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)&amp;lt;/tex&amp;gt;. При этом хранение КД-дерева требует &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26118</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26118"/>
				<updated>2012-06-20T12:01:57Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in \mathbb{R}^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = \{x^1, x^2, ..., x^n\} \subset \mathbb{R}^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | x \succ y\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\mu&amp;lt;/tex&amp;gt; - мера Лебега.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов, и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure&amp;lt;ref&amp;gt;Bringmann K., Friedrich. T.: An Efficient Algorithm for Computing Hypervolume Contributions. Evolutionary Computation, Vol. 18, No. 3, pp 383-402, MIT Press. (2010)&amp;lt;/ref&amp;gt; обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировавшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба к ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;. При этом точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритма напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются именно в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в &amp;lt;ref name = &amp;quot;while&amp;quot;/&amp;gt;. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и эта зависимость близка к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; &amp;lt;ref name=&amp;quot;while&amp;quot;&amp;gt;&lt;br /&gt;
While, L., Hingston, P., Barone, L., Huband, S.: A Faster Algorithm for Calculating Hypervolume. IEEE Transaction on Evolutionary Computation, Vol.10, No. 1, pp 29–38 (2006)&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;\mathbb{R}^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO&amp;lt;ref&amp;gt;Zhou X., Sun C., Mao N., Li W.: Generalization of HSO algortihms for computing hypervolume for mutiobjective optimization problems, IEEE Congress on Evolutionary Computation (2007)&amp;lt;/ref&amp;gt; рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения'' (разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' (гиперплоскости), проходящего перпендикулярно оси первой координаты, не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза, и умножить на длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все исходные &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, вторая - все, помимо точки с минимальной первой координатой, вдоль которой происходит расслоение, и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается их найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База:&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем полезные леммы:&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}^{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Переход: предполагаем, что утверждение верно для &amp;lt;tex&amp;gt;r = j&amp;lt;/tex&amp;gt;. Раскрываем первое слагаемое в правой части предположения аналогично базе и получаем: &lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - j - 1 \choose y} + {x - (j + 1) \choose y - 1} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1} = {x - (j + 1) \choose y} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Подставляем в предыдущую лемму &amp;lt;tex&amp;gt;r = x - y&amp;lt;/tex&amp;gt; и получаем:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {y \choose y} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = {x - (x - y + 1) \choose y - 1} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
продолжаем доказательство теоремы по индукции:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1} = \sum \limits_{i = 1}^{n} {n + d - 2 - i \choose d - 2} = \sum \limits_{k = n}^{1} {n + d + 2 - (n - k + 1) \choose d - 2} = \sum \limits_{k = 1}^{n} {k + d - 3 \choose d - 2} = \sum \limits_{k = 1}^{n}{k + (d - 1) - 2 \choose (d - 1) - 1} = \sum \limits_{k = 1}^{n}{f(k, d - 1)}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике &amp;lt;ref name =&amp;quot;while&amp;quot;/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP&amp;lt;ref name = &amp;quot;overmars&amp;quot;&amp;gt;Overmars M.H., Yap C.K.: New upper bounds in Klee’s measure problem. SIAM Journal on Computing 20(6), pp 1034–1045. (1991)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Beume N.: S-Metric calculation by considering dominated hypervolume as Klee’s measure problem. Evolutionary Computation, 17(4), pp 477–492. (2009)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Beume N., Rudolph G.: Faster S-metric calculation by considering dominated hypervolume as Klee’s measure problem. In Proc. Second International Conference on Computational Intelligence (IASTED ’06), pp 233–238. (2006)&lt;br /&gt;
&amp;lt;/ref&amp;gt;, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
В трехмерном пространстве сканирующая гиперплоскость превращается в обычную плоскость. Будем считать, что она всегда располагается перпендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; и двигается от минимальных значений по этой оси до максимальных. В каждый момент проекция всех параллелепипедов на эту плоскость представляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всей области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перпендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиеся &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе, возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой вертикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину дерева. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перпендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитываем площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат, получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все идеи этого алгоритма обобщаются с трехмерного пространства на &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерное следующим образом.&lt;br /&gt;
&lt;br /&gt;
Построение разбиения на области в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;), а также каждую &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.&lt;br /&gt;
&lt;br /&gt;
Это разбиение на области имеет следующие аналогичные свойства:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый гиперпараллелепипед частично покрывает не более &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Общее дерево строится аналогичным образом и оно в итоге состоит из &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уровней, каждый из которых имеет высоту &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый гиперпараллелепипед хранится в &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый гиперпараллелепипед влияет на &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности &amp;lt;tex&amp;gt;d-1&amp;lt;/tex&amp;gt;, в котором необходимо провести &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; операций, то есть суммарное время работы алгоритма равно: &amp;lt;tex&amp;gt;O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)&amp;lt;/tex&amp;gt;. При этом хранение КД-дерева требует &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26114</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26114"/>
				<updated>2012-06-20T11:58:40Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in \mathbb{R}^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = \{x^1, x^2, ..., x^n\} \subset \mathbb{R}^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | x \succ y\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\mu&amp;lt;/tex&amp;gt; - мера Лебега.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов, и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure&amp;lt;ref&amp;gt;K. Bringmann, T. Friedrich.: An Efficient Algorithm for Computing Hypervolume Contributions. Evolutionary Computation, Vol. 18, No. 3, pp 383-402, MIT Press. (2010)&amp;lt;/ref&amp;gt; обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировавшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба к ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;. При этом точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритма напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются именно в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в &amp;lt;ref name = &amp;quot;while&amp;quot;/&amp;gt;. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и эта зависимость близка к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; &amp;lt;ref name=&amp;quot;while&amp;quot;&amp;gt;&lt;br /&gt;
While, L., Hingston, P., Barone, L., Huband, S.: A Faster Algorithm for Calculating Hypervolume. IEEE Transaction on Evolutionary Computation, Vol.10, No. 1, pp 29–38 (2006)&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;\mathbb{R}^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO&amp;lt;ref&amp;gt;Zhou X., Sun C., Mao N., Li W.: Generalization of HSO algortihms for computing hypervolume for mutiobjective optimization problems, IEEE Congress on Evolutionary Computation (2007)&amp;lt;/ref&amp;gt; рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения'' (разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' (гиперплоскости), проходящего перпендикулярно оси первой координаты, не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза, и умножить на длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все исходные &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, вторая - все, помимо точки с минимальной первой координатой, вдоль которой происходит расслоение, и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается их найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База:&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем полезные леммы:&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}^{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Переход: предполагаем, что утверждение верно для &amp;lt;tex&amp;gt;r = j&amp;lt;/tex&amp;gt;. Раскрываем первое слагаемое в правой части предположения аналогично базе и получаем: &lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - j - 1 \choose y} + {x - (j + 1) \choose y - 1} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1} = {x - (j + 1) \choose y} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Подставляем в предыдущую лемму &amp;lt;tex&amp;gt;r = x - y&amp;lt;/tex&amp;gt; и получаем:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {y \choose y} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = {x - (x - y + 1) \choose y - 1} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
продолжаем доказательство теоремы по индукции:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1} = \sum \limits_{i = 1}^{n} {n + d - 2 - i \choose d - 2} = \sum \limits_{k = n}^{1} {n + d + 2 - (n - k + 1) \choose d - 2} = \sum \limits_{k = 1}^{n} {k + d - 3 \choose d - 2} = \sum \limits_{k = 1}^{n}{k + (d - 1) - 2 \choose (d - 1) - 1} = \sum \limits_{k = 1}^{n}{f(k, d - 1)}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике &amp;lt;ref name =&amp;quot;while&amp;quot;/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP&amp;lt;ref name = &amp;quot;overmars&amp;quot;&amp;gt;Overmars, M.H., Yap, C.K.: New upper bounds in Klee’s measure problem. SIAM Journal on Computing 20(6), pp 1034–1045. (1991)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;N. Beume.: S-Metric calculation by considering dominated hypervolume as Klee’s measure problem. Evolutionary Computation, 17(4), pp 477–492. (2009)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;N. Beume, G. Rudolph.: Faster S-metric calculation by considering dominated hypervolume as Klee’s measure problem. In Proc. Second International Conference on Computational Intelligence (IASTED ’06), pp 233–238. (2006)&lt;br /&gt;
&amp;lt;/ref&amp;gt;, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
В трехмерном пространстве сканирующая гиперплоскость превращается в обычную плоскость. Будем считать, что она всегда располагается перпендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; и двигается от минимальных значений по этой оси до максимальных. В каждый момент проекция всех параллелепипедов на эту плоскость представляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всей области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перпендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиеся &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе, возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой вертикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину дерева. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перпендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитываем площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат, получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все идеи этого алгоритма обобщаются с трехмерного пространства на &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерное следующим образом.&lt;br /&gt;
&lt;br /&gt;
Построение разбиения на области в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;), а также каждую &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.&lt;br /&gt;
&lt;br /&gt;
Это разбиение на области имеет следующие аналогичные свойства:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый гиперпараллелепипед частично покрывает не более &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Общее дерево строится аналогичным образом и оно в итоге состоит из &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уровней, каждый из которых имеет высоту &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый гиперпараллелепипед хранится в &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый гиперпараллелепипед влияет на &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности &amp;lt;tex&amp;gt;d-1&amp;lt;/tex&amp;gt;, в котором необходимо провести &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; операций, то есть суммарное время работы алгоритма равно: &amp;lt;tex&amp;gt;O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)&amp;lt;/tex&amp;gt;. При этом хранение КД-дерева требует &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26104</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=26104"/>
				<updated>2012-06-20T11:48:56Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in \mathbb{R}^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = \{x^1, x^2, ..., x^n\} \subset \mathbb{R}^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | x \succ y\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\mu&amp;lt;/tex&amp;gt; - мера Лебега.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов, и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure&amp;lt;ref&amp;gt;K. Bringmann, T. Friedrich.: An Efficient Algorithm for Computing Hypervolume Contributions. Evolutionary Computation, Vol. 18, No. 3, pp 383-402, MIT Press. (2010)&amp;lt;/ref&amp;gt; обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба к ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;. При этом точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритма напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются именно в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и эта зависимость близка к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; &amp;lt;ref name=&amp;quot;while&amp;quot;&amp;gt;&lt;br /&gt;
While, L., Hingston, P., Barone, L., Huband, S.: A Faster Algorithm for Calculating Hypervolume. IEEE Transaction on Evolutionary Computation, Vol.10, No. 1, pp 29–38 (2006)&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;\mathbb{R}^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO&amp;lt;ref&amp;gt;Zhou X., Sun C., Mao N., Li W.: Generalization of HSO algortihms for computing hypervolume for mutiobjective optimization problems, IEEE Congress on Evolutionary Computation (2007)&amp;lt;/ref&amp;gt; рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения'' (разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' (гиперплоскости), проходящего перпендикулярно оси первой координаты, не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза, и умножить на длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все исходные &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, вторая - все, помимо точки с минимальной первой координатой, вдоль которой происходит расслоение, и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается их найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База:&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем полезные леммы:&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}^{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Переход: предполагаем, что утверждение верно для &amp;lt;tex&amp;gt;r = j&amp;lt;/tex&amp;gt;. Раскрываем первое слагаемое в правой части предположения аналогично базе и получаем: &lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - j - 1 \choose y} + {x - (j + 1) \choose y - 1} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1} = {x - (j + 1) \choose y} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Подставляем в предыдущую лемму &amp;lt;tex&amp;gt;r = x - y&amp;lt;/tex&amp;gt; и получаем:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {y \choose y} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = {x - (x - y + 1) \choose y - 1} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
продолжаем доказательство теоремы по индукции:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1} = \sum \limits_{i = 1}^{n} {n + d - 2 - i \choose d - 2} = \sum \limits_{k = n}^{1} {n + d + 2 - (n - k + 1) \choose d - 2} = \sum \limits_{k = 1}^{n} {k + d - 3 \choose d - 2} = \sum \limits_{k = 1}^{n}{k + (d - 1) - 2 \choose (d - 1) - 1} = \sum \limits_{k = 1}^{n}{f(k, d - 1)}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике &amp;lt;ref name =&amp;quot;while&amp;quot;/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP&amp;lt;ref name = &amp;quot;overmars&amp;quot;&amp;gt;Overmars, M.H., Yap, C.K.: New upper bounds in Klee’s measure problem. SIAM Journal on Computing 20(6), pp 1034–1045. (1991)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;N. Beume.: S-Metric calculation by considering dominated hypervolume as Klee’s measure problem. Evolutionary Computation, 17(4), pp 477–492. (2009)&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;N. Beume, G. Rudolph.: Faster S-metric calculation by considering dominated hypervolume as Klee’s measure problem. In Proc. Second International Conference on Computational Intelligence (IASTED ’06), pp 233–238. (2006)&lt;br /&gt;
&amp;lt;/ref&amp;gt;, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
В трехмерном пространстве сканирующая гиперплоскость превращается в обычную плоскость. Будем считать, что она всегда располагается перепендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; и двигается от минимальных значений по этой оси до максимальных. В каждый момент проекция всех параллелепипедов на эту плоскость представляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всей области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перепендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиеся &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе, возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой верикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину дерева. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перепендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитываем площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат, получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все идеи этого алгоритма обобщаются с трехмерного пространства на &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерное следующим образом.&lt;br /&gt;
&lt;br /&gt;
Построение разбиения на области в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;), а также каждую &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.&lt;br /&gt;
&lt;br /&gt;
Это разбиение на области имеет следующие аналогичные свойства:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый гиперпараллелепипед частично покрывает не более &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Общее дерево строится аналогичным образом и оно в итоге состоит из &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уровней, каждый из которых имеет высоту &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый гиперпараллелепипед хранится в &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый гиперпараллелепипед влияет на &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности &amp;lt;tex&amp;gt;d-1&amp;lt;/tex&amp;gt;, в котором необходимо провести &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; операций, то есть суммарное время работы алгоритма равно: &amp;lt;tex&amp;gt;O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)&amp;lt;/tex&amp;gt;. При этом хранение КД-дерева требует &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25602</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25602"/>
				<updated>2012-06-18T06:43:17Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: орфографические ошибки&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | x \succ y\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов, и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба к ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;. При этом точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритма напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются именно в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и эта зависимость близка к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; [1].&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;R^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения'' (разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' (гиперплоскости), проходящего перпендикулярно оси первой координаты, не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза, и умножить на длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все исходные &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, вторая - все, помимо точки с минимальной первой координатой, вдоль которой происходит расслоение, и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается их найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База:&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем полезные леммы:&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}^{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Переход: предполагаем, что утверждение верно для &amp;lt;tex&amp;gt;r = j&amp;lt;/tex&amp;gt;. Раскрываем первое слагаемое в правой части предположения аналогично базе и получаем: &lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - j - 1 \choose y} + {x - (j + 1) \choose y - 1} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1} = {x - (j + 1) \choose y} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Подставляем в предыдущую лемму &amp;lt;tex&amp;gt;r = x - y&amp;lt;/tex&amp;gt; и получаем:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {y \choose y} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = {x - (x - y + 1) \choose y - 1} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
продолжаем доказательство теоремы по индукции:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1} = \sum \limits_{i = 1}^{n} {n + d - 2 + i \choose d - 2} = \sum \limits_{k = n}^{1} {n + d + 2 - (n - k + 1) \choose d - 2} = \sum \limits_{k = 1}^{n} {k + d - 3 \choose d - 2} = \sum \limits_{k = 1}^{n}{k + (d - 1) - 2 \choose (d - 1) - 1} = \sum \limits_{k = 1}^{n}{f(k, d - 1)}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике [1].&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
Будем считать, что сканирующая плоскость двигается перепендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;. В каждый момент проекция всех параллелепипедов на эту плоскость предствляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространства, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всей области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перепендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиеся &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе, возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой верикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину дерева. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перепендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитываем площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат, получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все идеи этого алгоритма обобщаются с трехмерного пространства на &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерное следующим образом.&lt;br /&gt;
&lt;br /&gt;
Построение разбиения на области в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;), а также каждую &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.&lt;br /&gt;
&lt;br /&gt;
Это разбиение на области имеет следующие аналогичные свойства:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый гиперпараллелепипед частично покрывает не более &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Общее дерево строится аналогичным образом и оно в итоге состоит из &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уровней, каждый из которых имеет высоту &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый гиперпараллелепипед хранится в &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый гиперпараллелепипед влияет на &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности &amp;lt;tex&amp;gt;d-1&amp;lt;/tex&amp;gt;, в котором необходимо провести &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; операций, то есть суммарное время работы алгоритма равно: &amp;lt;tex&amp;gt;O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)&amp;lt;/tex&amp;gt;. При этом хранение КД-дерева требует &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
# While, L., Hingston, P., Barone, L., Huband, S.: A Faster Algorithm for Calculating Hypervolume. IEEE Transaction on Evolutionary Computation, Vol.10, No. 1, pp 29–38 (2006)&lt;br /&gt;
# [http://rain.ifmo.ru/~tsarev/teaching/ea-2012/seminars/1320.pdf Zhou X., Sun C., Mao N., Li W.: Generalization of HSO algortihms for computing hypervolume for mutiobjective optimization problems, IEEE Congress on Evolutionary Computation (2007)]&lt;br /&gt;
# K. Bringmann, T. Friedrich.: An Efficient Algorithm for Computing Hypervolume Contributions. Evolutionary Computation, Vol. 18, No. 3, pp 383-402, MIT Press. (2010)&lt;br /&gt;
# N. Beume.: S-Metric calculation by considering dominated hypervolume as Klee’s measure problem. Evolutionary Computation, 17(4), pp 477–492. (2009)&lt;br /&gt;
# N. Beume, G. Rudolph.: Faster S-metric calculation by considering dominated hypervolume as Klee’s measure problem. In Proc. Second International Conference on Computational Intelligence (IASTED ’06), pp 233–238. (2006)&lt;br /&gt;
# Overmars, M.H., Yap, C.K.: New upper bounds in Klee’s measure problem. SIAM Journal on Computing 20(6), pp 1034–1045. (1991)&lt;br /&gt;
# Klee, V.: Can the measure of S[ai, bi] be computed in less than O(n log n) steps? In: American Mathematical Monthly. Volume 84, pp 284–285. (1977)&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25586</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25586"/>
				<updated>2012-06-17T23:20:59Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба в ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;. При этом точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и близок к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; [1].&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;R^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения''(разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' перпендикулярно оси первой координаты не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза и умножить длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек, вторая - все, помимо точки с минимальной координатой, вдоль которой происходит расслоение и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База:&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем полезные леммы:&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}^{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Переход: предполагаем, что утверждение верно для &amp;lt;tex&amp;gt;r = j&amp;lt;/tex&amp;gt;. Раскрываем первое слагаемое в правой части предположения, аналогично базе и получаем: &lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - j - 1 \choose y} + {x - (j + 1) \choose y - 1} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1} = {x - (j + 1) \choose y} + \sum \limits_{i = 1}^{j}{x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Подставляем в предыдущую лемму &amp;lt;tex&amp;gt;r = x - y&amp;lt;/tex&amp;gt; и получаем:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {y \choose y} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = {x - (x - y + 1) \choose y - 1} + \sum \limits_{i = 1}^{x - y} {x - i \choose y - 1} = \sum \limits_{i = 1}^{x - y + 1} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
продолжаем доказательство теоремы по индукции:&lt;br /&gt;
&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1} = \sum \limits_{i = 1}^{n} {n + d - 2 + i \choose d - 2} = \sum \limits_{k = n}^{1} {n + d + 2 - (n - k + 1) \choose d - 2} = \sum \limits_{k = 1}^{n} {k + d - 3 \choose d - 2} = \sum \limits_{k = 1}^{n}{k + (d - 1) - 2 \choose (d - 1) - 1} = \sum \limits_{k = 1}^{n}{f(k, d - 1)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике [1].&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
Будем считать, что сканирующая плоскость двигается перепендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;. В каждый момент проекция всех параллелепипедов на эту плоскость предствляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространстве, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всех области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перепендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиемя &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой верикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перепендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитывается площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все идеи этого алгоритма обобщаются с трехмерного пространства на &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерное следующим образом.&lt;br /&gt;
&lt;br /&gt;
Построение разбиения на области в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;), а также каждую &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.&lt;br /&gt;
&lt;br /&gt;
Это разбиение на области имеет следующие аналогичные свойства:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый гиперпараллелепипед частично покрывает не более &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Общее дерево строится аналогичным образом и оно в итоге состоит из &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уровней, каждый из которых имеет высоту &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый гиперпараллелепипед хранится в &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый гиперпараллелепипед влияет на &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности &amp;lt;tex&amp;gt;d-1&amp;lt;/tex&amp;gt;, в котором необходимо провести &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; операций, то есть суммарное время работы алгоритма равно: &amp;lt;tex&amp;gt;O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)&amp;lt;/tex&amp;gt;. При этом хранение КД-дерева требует &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
# While, L., Hingston, P., Barone, L., Huband, S.: A Faster Algorithm for Calculating Hypervolume. IEEE Transaction on Evolutionary Computation, Vol.10, No. 1, pp 29–38 (2006)&lt;br /&gt;
# [http://rain.ifmo.ru/~tsarev/teaching/ea-2012/seminars/1320.pdf Zhou X., Sun C., Mao N., Li W.: Generalization of HSO algortihms for computing hypervolume for mutiobjective optimization problems, IEEE Congress on Evolutionary Computation (2007)]&lt;br /&gt;
# K. Bringmann, T. Friedrich.: An Efficient Algorithm for Computing Hypervolume Contributions. Evolutionary Computation, Vol. 18, No. 3, pp 383-402, MIT Press. (2010)&lt;br /&gt;
# N. Beume.: S-Metric calculation by considering dominated hypervolume as Klee’s measure problem. Evolutionary Computation, 17(4), pp 477–492. (2009)&lt;br /&gt;
# N. Beume, G. Rudolph.: Faster S-metric calculation by considering dominated hypervolume as Klee’s measure problem. In Proc. Second International Conference on Computational Intelligence (IASTED ’06), pp 233–238. (2006)&lt;br /&gt;
# Overmars, M.H., Yap, C.K.: New upper bounds in Klee’s measure problem. SIAM Journal on Computing 20(6), pp 1034–1045. (1991)&lt;br /&gt;
# Klee, V.: Can the measure of S[ai, bi] be computed in less than O(n log n) steps? In: American Mathematical Monthly. Volume 84, pp 284–285. (1977)&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25582</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25582"/>
				<updated>2012-06-17T22:35:37Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, &amp;lt;/center&amp;gt; то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба в ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;При этом, точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и близок к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; [1].&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;R^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения''(разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' перпендикулярно оси первой координаты не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза и умножить длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек, вторая - все, помимо точки с минимальной координатой, вдоль которой происходит расслоение и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем полезные леммы:&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике [1].&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
Будем считать, что сканирующая плоскость двигается перепендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;. В каждый момент проекция всех параллелепипедов на эту плоскость предствляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространстве, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всех области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перепендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиемя &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой верикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перепендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитывается площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все идеи этого алгоритма обобщаются с трехмерного пространства на &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерное следующим образом.&lt;br /&gt;
&lt;br /&gt;
Построение разбиения на области в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;), а также каждую &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.&lt;br /&gt;
&lt;br /&gt;
Это разбиение на области имеет следующие аналогичные свойства:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый гиперпараллелепипед частично покрывает не более &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Общее дерево строится аналогичным образом и оно в итоге состоит из &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уровней, каждый из которых имеет высоту &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый гиперпараллелепипед хранится в &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый гиперпараллелепипед влияет на &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности &amp;lt;tex&amp;gt;d-1&amp;lt;/tex&amp;gt;, в котором необходимо провести &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; операций, то есть суммарное время работы алгоритма равно: &amp;lt;tex&amp;gt;O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)&amp;lt;/tex&amp;gt;. При этом хранение КД-дерева требует &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
# While, L., Hingston, P., Barone, L., Huband, S.: A Faster Algorithm for Calculating Hypervolume. IEEE Transaction on Evolutionary Computation, Vol.10, No. 1, pp 29–38 (2006)&lt;br /&gt;
# Zhou X., Sun C., Mao N., Li W.: Generalization of HSO algortihms for computing hypervolume for mutiobjective optimization problems, IEEE Congress on Evolutionary Computation (2007)&lt;br /&gt;
# K. Bringmann, T. Friedrich.: An Efficient Algorithm for Computing Hypervolume Contributions. Evolutionary Computation, Vol. 18, No. 3, pp 383-402, MIT Press. (2010)&lt;br /&gt;
# N. Beume.: S-Metric calculation by considering dominated hypervolume as Klee’s measure problem. Evolutionary Computation, 17(4), pp 477–492. (2009)&lt;br /&gt;
# N. Beume, G. Rudolph.: Faster S-metric calculation by considering dominated hypervolume as Klee’s measure problem. In Proc. Second International Conference on Computational Intelligence (IASTED ’06), pp 233–238. (2006)&lt;br /&gt;
# Overmars, M.H., Yap, C.K.: New upper bounds in Klee’s measure problem. SIAM Journal on Computing 20(6), pp 1034–1045. (1991)&lt;br /&gt;
# Klee, V.: Can the measure of S[ai, bi] be computed in less than O(n log n) steps? In: American Mathematical Monthly. Volume 84, pp 284–285. (1977)&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25579</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25579"/>
				<updated>2012-06-17T22:19:38Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, &amp;lt;/center&amp;gt; то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба в ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;При этом, точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и близок к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; [1].&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;R^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения''(разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' перпендикулярно оси первой координаты не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза и умножить длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек, вторая - все, помимо точки с минимальной координатой, вдоль которой происходит расслоение и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1) Покажем, что: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике [1].&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
Будем считать, что сканирующая плоскость двигается перепендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;. В каждый момент проекция всех параллелепипедов на эту плоскость предствляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространстве, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всех области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перепендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиемя &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой верикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перепендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитывается площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все идеи этого алгоритма обобщаются с трехмерного пространства на &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерное следующим образом.&lt;br /&gt;
&lt;br /&gt;
Построение разбиения на области в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;), а также каждую &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt;-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.&lt;br /&gt;
&lt;br /&gt;
Это разбиение на области имеет следующие аналогичные свойства:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый гиперпараллелепипед частично покрывает не более &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Общее дерево строится аналогичным образом и оно в итоге состоит из &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; уровней, каждый из которых имеет высоту &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.&lt;br /&gt;
&lt;br /&gt;
Построенное КД-дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
# Каждый гиперпараллелепипед хранится в &amp;lt;tex&amp;gt;O(n^{(d-1)/2})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый гиперпараллелепипед влияет на &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее гиперпараллелепипедов.&lt;br /&gt;
&lt;br /&gt;
Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n^{(d-1)/2} \log n)&amp;lt;/tex&amp;gt; времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности &amp;lt;tex&amp;gt;d-1&amp;lt;/tex&amp;gt;, в котором необходимо провести &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; операций, то есть суммарное время работы алгоритма равно: &amp;lt;tex&amp;gt;O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)&amp;lt;/tex&amp;gt;. При этом хранение КД-дерева требует &amp;lt;tex&amp;gt;O(n^{d/2})&amp;lt;/tex&amp;gt; памяти.&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25577</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25577"/>
				<updated>2012-06-17T21:49:06Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, &amp;lt;/center&amp;gt; то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба в ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;При этом, точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и близок к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; [1].&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;R^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения''(разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' перпендикулярно оси первой координаты не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза и умножить длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек, вторая - все, помимо точки с минимальной координатой, вдоль которой происходит расслоение и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1) Покажем, что: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике [1].&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
Будем считать, что сканирующая плоскость двигается перепендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;. В каждый момент проекция всех параллелепипедов на эту плоскость предствляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространстве, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всех области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования.&lt;br /&gt;
Возьмем проекции всех параллелепипедов на плоскость, перепендикулярную оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt; - множество прямоугольников &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;. Рассмотрим все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;-координаты границ прямоугольников и разобьем ось &amp;lt;tex&amp;gt;OX&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; промежутков так, чтобы в каждом из них было не более &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt; границ. Получившиемя &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt; полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе возьмем все горизонтальные границы (их будет не более &amp;lt;tex&amp;gt;2\sqrt{n}&amp;lt;/tex&amp;gt;), а среди всех горизонтальных границ, пересекающих область, возьмем каждую &amp;lt;tex&amp;gt;\sqrt{n}&amp;lt;/tex&amp;gt;-ую. Таким образом, в итоге получим не более &amp;lt;tex&amp;gt;4\sqrt{n}&amp;lt;/tex&amp;gt; областей в каждой верикальной полосе.&lt;br /&gt;
&lt;br /&gt;
Полученные области обладают следующими свойствами:&lt;br /&gt;
# Всего &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник частично покрывает не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри какой-нибудь области.&lt;br /&gt;
# Для каждой области есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти утверждения несложно следуют из алгоритма разбиения на области.&lt;br /&gt;
&lt;br /&gt;
Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.&lt;br /&gt;
&lt;br /&gt;
Построенное дерево обладает следующими свойствами:&lt;br /&gt;
# В нем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; областей.&lt;br /&gt;
# Каждый прямоугольник хранится в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьях.&lt;br /&gt;
# Каждый прямоугольник влияет на &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; значений &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.&lt;br /&gt;
# Для области каждого листа есть не более &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; частично покрывающих ее прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.&lt;br /&gt;
&lt;br /&gt;
Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перепендикулярной оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;, добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитывается площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;-координат получаем общий объем.&lt;br /&gt;
&lt;br /&gt;
Каждая операция добавления или удаления прямоугольников требует изменения &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; полей &amp;lt;tex&amp;gt;Cover&amp;lt;/tex&amp;gt;, а также операций добавления или удаления прямоугольника в &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; листьев, каждая из которых требует &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; времени. Итого, на одну операцию добавления или удаления требуется &amp;lt;tex&amp;gt;O(\sqrt{n} \log n)&amp;lt;/tex&amp;gt; времени, суммарно таких операций &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, и получается, что весь алгоритм работает за &amp;lt;tex&amp;gt;O(n \sqrt{n} \log n)&amp;lt;/tex&amp;gt;. При этом на хранение всей информации требуется &amp;lt;tex&amp;gt;O(n\sqrt{n}) &amp;lt;/tex&amp;gt; памяти - каждый лист может хранить &amp;lt;tex&amp;gt;O(\sqrt{n})&amp;lt;/tex&amp;gt; прямоугольников.&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25566</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25566"/>
				<updated>2012-06-17T20:35:16Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, &amp;lt;/center&amp;gt; то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба в ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;При этом, точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и близок к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; [1].&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;R^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения''(разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' перпендикулярно оси первой координаты не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза и умножить длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек, вторая - все, помимо точки с минимальной координатой, вдоль которой происходит расслоение и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1) Покажем, что: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}{r} {x - i \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Индукция по &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике [1].&lt;br /&gt;
&lt;br /&gt;
== Сведение к задаче KMP (Klee's Measure Problem) ==&lt;br /&gt;
&lt;br /&gt;
Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.&lt;br /&gt;
&lt;br /&gt;
Существует несколько алгоритмов решения задачи KMP, самый оптимальный из которых использует идеи сканирующей гиперплоскости, [[Статистики на отрезках. Корневая эвристика|корневой эвристики]] и КД-дерево, и позволяет решать задачу за время &amp;lt;tex&amp;gt;O(n^{d/2}\log n)&amp;lt;/tex&amp;gt;. Рассмотрим его.&lt;br /&gt;
&lt;br /&gt;
Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты у точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Возьмем гиперплоскость, перпендикулярную оси &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.&lt;br /&gt;
&lt;br /&gt;
Теперь изложим идею алгоритма на примере трехмерного пространства.&lt;br /&gt;
Будем считать, что сканирующая плоскость двигается перепендикулярно оси &amp;lt;tex&amp;gt;OZ&amp;lt;/tex&amp;gt;. В каждый момент проекция всех параллелепипедов на эту плоскость предствляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:&lt;br /&gt;
# добавить прямоугольник&lt;br /&gt;
# удалить прямоугольник&lt;br /&gt;
# посчитать площадь объединения всех прямоугольников&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=КД-деревом называется [[Дерево поиска, наивная реализация|сбалансированное двоичное дерево]], где каждой вершине &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; соответствует некоторая область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространстве, удовлетворяющая следующим свойствам:&lt;br /&gt;
# Корневой вершине &amp;lt;tex&amp;gt;root&amp;lt;/tex&amp;gt; соответствует &amp;lt;tex&amp;gt;C_{root}&amp;lt;/tex&amp;gt; - все пространство.&lt;br /&gt;
# Каждое &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).&lt;br /&gt;
# Для каждой вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; с детьми &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\gamma&amp;lt;/tex&amp;gt; верно, что области &amp;lt;tex&amp;gt;C_{\beta}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_{\gamma}&amp;lt;/tex&amp;gt; не пересекаются и &amp;lt;tex&amp;gt;C_{\alpha} = C_{\beta} \cup C_{\gamma}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Будем хранить прямоугольники в КД-дереве следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем хранить все прямоугольники, которые пересекают внутреннюю часть области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; будем считать число &amp;lt;tex&amp;gt;Cover_{\alpha}&amp;lt;/tex&amp;gt; - количество прямоугольников, которые полностью покрывают область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, но не полностью покрывают область родителя этой вершины &amp;lt;tex&amp;gt;C_{father(\alpha)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, которое определяется следующим образом:&lt;br /&gt;
# Для каждого листа &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади пересечения всех прямоугольников с областью этого листа.&lt;br /&gt;
# Для каждой внутренней вершины &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно площади всех области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;, иначе &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; равно сумме этих значений для двух сыновей этой вершины.&lt;br /&gt;
&lt;br /&gt;
Таким образом, значение для корневой вершины &amp;lt;tex&amp;gt;M_{root}&amp;lt;/tex&amp;gt; и является искомой площадью объединения всех прямоугольников.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.&lt;br /&gt;
&lt;br /&gt;
  procedure Insert(box, &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  if &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; - лист then&lt;br /&gt;
    добавить box в эту вершину&lt;br /&gt;
    пересчитать &amp;lt;tex&amp;gt;M_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box покрывает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    &amp;lt;tex&amp;gt;Cover_{\alpha} = Cover_{\alpha} + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  elseif box пересекает область &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt; then&lt;br /&gt;
    Insert(box, leftson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    Insert(box, rightson(&amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;))&lt;br /&gt;
    if &amp;lt;tex&amp;gt;Cover_{\alpha} &amp;gt; 0 &amp;lt;/tex&amp;gt; then&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = &amp;lt;/tex&amp;gt; объем области &amp;lt;tex&amp;gt;C_{\alpha}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      &amp;lt;tex&amp;gt;M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25538</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25538"/>
				<updated>2012-06-17T18:54:57Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, &amp;lt;/center&amp;gt; то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба в ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;При этом, точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и близок к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; [1].&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;R^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения''(разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' перпендикулярно оси первой координаты не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза и умножить длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек, вторая - все, помимо точки с минимальной координатой, вдоль которой происходит расслоение и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;. Тем не менее, существует более точная оценка.&lt;br /&gt;
&lt;br /&gt;
{{Теорема &lt;br /&gt;
|statement=Суммарное количество частей, полученных алгоритмом HSO, не превышает &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = {n + d - 2 \choose d - 1}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|proof=&lt;br /&gt;
База: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, 1) = 1&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также, из алгоритма расслоения следует, что из части с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точками будет получено по одной части для каждого &amp;lt;tex&amp;gt;i = 1...n&amp;lt;/tex&amp;gt;, то есть: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25529</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25529"/>
				<updated>2012-06-17T18:15:08Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, &amp;lt;/center&amp;gt; то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба в ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;При этом, точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и близок к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; [1].&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Hypervolume by Slicing Objectives (HSO) ==&lt;br /&gt;
&lt;br /&gt;
Под ''Objectives'' в названии данного алгоритма имеются в виду координаты пространства &amp;lt;tex&amp;gt;R^d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.&lt;br /&gt;
&lt;br /&gt;
Изначально все точки сортируются по первой координате. Значения этой координаты используются для ''расслоения''(разрезания) всего множества на &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; частей, внутри каждой из которых при движении вдоль первой координаты форма ''разреза'' перпендикулярно оси первой координаты не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза и умножить длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность.&lt;br /&gt;
Заметим, что после сортировки и расслоения первая часть содержит все &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек, вторая - все, помимо точки с минимальной координатой, вдоль которой происходит расслоение и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.&lt;br /&gt;
&lt;br /&gt;
После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.&lt;br /&gt;
&lt;br /&gt;
Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.&lt;br /&gt;
&lt;br /&gt;
Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество.&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25526</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25526"/>
				<updated>2012-06-17T17:49:16Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, &amp;lt;/center&amp;gt; то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба в ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;При этом, точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; имеет вид: &amp;lt;tex&amp;gt;(1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)&amp;lt;/tex&amp;gt;, и точки обрабатываются в этом порядке, то всего будет обработано &amp;lt;tex&amp;gt;n^{d-1}&amp;lt;/tex&amp;gt; точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; и близок к &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt; [1].&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25523</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25523"/>
				<updated>2012-06-17T17:40:26Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм LebMeasure ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм LebMeasure обрабатывает точки множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; по очереди. Для каждой очередной точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и она заменяется на некоторое множество ''порожденных'' точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например, если изначально было четыре точки в трехмерном пространстве &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)&amp;lt;/tex&amp;gt;, &amp;lt;/center&amp;gt; то точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; эксклюзивно доминирует куб с одним концов в &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt;, а другим - в &amp;lt;tex&amp;gt;(4, 5, 3)&amp;lt;/tex&amp;gt;. После добавления объема этого куба в ответу, точка &amp;lt;tex&amp;gt;(6, 7, 4)&amp;lt;/tex&amp;gt; порождает три точки: &amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;(4, 7, 4), (6, 5, 3), (6, 7, 3)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;При этом, точка &amp;lt;tex&amp;gt;(6, 5, 4)&amp;lt;/tex&amp;gt; доминируется точкой &amp;lt;tex&amp;gt;(9, 5, 5)&amp;lt;/tex&amp;gt; и сразу удаляется из множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем &amp;lt;tex&amp;gt;n^d&amp;lt;/tex&amp;gt;, поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25520</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25520"/>
				<updated>2012-06-17T17:20:49Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X = (x^1, x^2, ..., x^n) \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение гиперобъема &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt; множества из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерного пространоства.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA) ==&lt;br /&gt;
&lt;br /&gt;
Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной [[формула включения-исключения|формулы включения-искючения]].&lt;br /&gt;
Все множество &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; представляется в виде объединения &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; гиперкубов (&amp;lt;tex&amp;gt;X^i&amp;lt;/tex&amp;gt;), соответствующих отдельным точкам &amp;lt;tex&amp;gt;x^i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После этого объем всего множества вычисляется по формуле: &amp;lt;center&amp;gt; &amp;lt;tex&amp;gt; S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1}  S(\bigcap \limits_{ j \in I} X^j) &amp;lt;/tex&amp;gt; &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.&lt;br /&gt;
&lt;br /&gt;
Таким образом, в этом алгоритме перебираются все подмножества точек множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу.&lt;br /&gt;
Время работы этого алгоритма составляет &amp;lt;tex&amp;gt;O(n 2^n)&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25512</id>
		<title>Алгоритмы точного вычисления гиперобъема</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D0%B8%D0%BF%D0%B5%D1%80%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC%D0%B0&amp;diff=25512"/>
				<updated>2012-06-17T16:59:19Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: Новая страница: «{{В разработке}}  == Постановка задачи == &amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерн...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&amp;lt;tex&amp;gt;x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d&amp;lt;/tex&amp;gt; - точка в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве.&lt;br /&gt;
&lt;br /&gt;
Точка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; доминирует точку &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;x \succ y&amp;lt;/tex&amp;gt;), если &amp;lt;tex&amp;gt;\forall i : x_i \ge y_i, \exists j : x_j &amp;gt; y_j&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X \subset R^d&amp;lt;/tex&amp;gt; - множество из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-мерном пространстве таких, что &amp;lt;tex&amp;gt;\nexists i \neq j : x_i \succ x_j&amp;lt;/tex&amp;gt; - никакая точка не доминируется другой точкой из этого множества.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) &amp;lt;/tex&amp;gt; - гиперобъем множества &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В частности, если &amp;lt;tex&amp;gt;X = \{x\}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;S(X) = \prod \limits_{i=1}^{d} x_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Задача: найти точное значение &amp;lt;tex&amp;gt;S(X)&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BB%D0%B0%D1%81%D1%81_PCP&amp;diff=1320</id>
		<title>Класс PCP</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BB%D0%B0%D1%81%D1%81_PCP&amp;diff=1320"/>
				<updated>2010-06-01T12:42:54Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Определение==&lt;br /&gt;
Классом '''PCP[r(n), q(n)]''' ('''PCP''' - Probabilistically Checkable Proof), где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - длина входного слова, называется множество языков, распознаваемых машиной &amp;lt;tex&amp;gt;V^{\pi}(x)&amp;lt;/tex&amp;gt;, обладающей следующими свойствами:&lt;br /&gt;
&lt;br /&gt;
# Время работы &amp;lt;tex&amp;gt;V^{\pi}(x)&amp;lt;/tex&amp;gt; ограничено сверху некоторым полиномом от длины &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; - некоторая строка, выступающая в качестве средства доказательства (аналогично P в [[Класс IP|интерактивном протоколе доказательства]]). Очевидно, ее длина не превосходит 2&amp;lt;sup&amp;gt;poly(x)&amp;lt;/sup&amp;gt;, так как только к такому множеству позиций сможет обратиться &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; - [[Вероятностная машина Тьюринга|вероятностная машина Тьюринга]], обращающаяся к случайной ленте не более &amp;lt;tex&amp;gt;r(n)&amp;lt;/tex&amp;gt; раз.&lt;br /&gt;
# &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; обращается к строке &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; не более &amp;lt;tex&amp;gt;q(n)&amp;lt;/tex&amp;gt; раз.&lt;br /&gt;
# &amp;lt;tex&amp;gt;x \in L \Rightarrow \exists \pi : Pr(V^{\pi}(x)=1)=1 \ &amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;Pr(V^{\pi}(x)=1)&amp;lt;/tex&amp;gt; - вероятность того, что &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; допустит &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# &amp;lt;tex&amp;gt;\  x \notin L \Rightarrow \forall \pi : Pr(V^{\pi}(x)=1)\le \frac{1}{2} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства==&lt;br /&gt;
&lt;br /&gt;
# '''PCP[0, 0] = [[P|P]]''' (по определению '''P''' - нет случайности и обращений к &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;)&lt;br /&gt;
# '''PCP[log(n), 0] = [[P|P]]''' (логарифмическое число обращений к случайной ленте не помогают, так как можно за полиномиальное время перебрать всевозможные результаты обращений)&lt;br /&gt;
# '''PCP[0, log(n)] = [[P|P]]''' (логарифмическое число обращений к строке &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; также не помогают, так как можно аналогичным образом перебрать всевозможные результаты обращений за полиномиальное время)&lt;br /&gt;
# '''PCP[poly(n), 0] = [[Сложностные_классы_RP_и_coRP|coRP]]''' (по определению '''coRP''')&lt;br /&gt;
# '''PCP[0, poly(n)] = [[NP|NP]]''' (по определению '''NP''' на языке сертификатов)&lt;br /&gt;
# '''PCP[log(n), O(1)] = [[NP|NP]]''' ([[PCP-теорема]])&lt;br /&gt;
&lt;br /&gt;
==Теорема==&lt;br /&gt;
&lt;br /&gt;
'''[[GNI]]''' ∈ '''PCP[poly(n), O(1)]'''&lt;br /&gt;
&lt;br /&gt;
==Доказательство==&lt;br /&gt;
&lt;br /&gt;
Алгоритм работы машины '''V''' аналогичен алгоритму работы при доказательстве того, что '''[[GNI]]''' ∈ '''IP'''.&lt;br /&gt;
&lt;br /&gt;
В строке &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; для каждого графа (введена некоторая нумерация графов) записано, кому из данных графов &amp;lt;tex&amp;gt;G_1, G_2&amp;lt;/tex&amp;gt; он изоморфен.&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BB%D0%B0%D1%81%D1%81_PCP&amp;diff=1318</id>
		<title>Класс PCP</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%BB%D0%B0%D1%81%D1%81_PCP&amp;diff=1318"/>
				<updated>2010-06-01T12:25:54Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: /* Свойства */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Определение==&lt;br /&gt;
Классом '''PCP[r(n), q(n)]''' ('''PCP''' - Probabilistically Checkable Proof), где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; - длина входного слова, называется множество языков, распознаваемых машиной &amp;lt;tex&amp;gt;V^{\pi}(x)&amp;lt;/tex&amp;gt;, обладающей следующими свойствами:&lt;br /&gt;
&lt;br /&gt;
1) Время работы &amp;lt;tex&amp;gt;V^{\pi}(x)&amp;lt;/tex&amp;gt; ограничено сверху некоторым полиномом от длины &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; - некоторая строка, выступающая в качестве средства доказательства (аналогично P в [[Класс IP|интерактивном протоколе доказательства]]). Очевидно, ее длина не превосходит 2&amp;lt;sup&amp;gt;poly(x)&amp;lt;/sup&amp;gt;, так как только к такому множеству позиций сможет обратиться &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; - [[Вероятностная машина Тьюринга|вероятностная машина Тьюринга]], обращающаяся к случайной ленте не более &amp;lt;tex&amp;gt;r(n)&amp;lt;/tex&amp;gt; раз&lt;br /&gt;
&lt;br /&gt;
4) &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; обращается к строке &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; не более &amp;lt;tex&amp;gt;q(n)&amp;lt;/tex&amp;gt; раз&lt;br /&gt;
&lt;br /&gt;
5) &amp;lt;tex&amp;gt;x \in L \Rightarrow \exists \pi : Pr(V^{\pi}(x)=1)=1 \ &amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;Pr(V^{\pi}(x)=1)&amp;lt;/tex&amp;gt; - вероятность того, что &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; допустит &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6) &amp;lt;tex&amp;gt;\  x \notin L \Rightarrow \forall \pi : Pr(V^{\pi}(x)=1)\le \frac{1}{2} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Свойства==&lt;br /&gt;
&lt;br /&gt;
1) '''PCP[0, 0] = [[P|P]]''' (по определению '''P''' - нет случайности и обращений к &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
2) '''PCP[log(n), 0] = [[P|P]]''' (логарифмическое число обращений к случайной ленте не помогают, так как можно за полиномиальное время перебрать всевозможные результаты обращений)&lt;br /&gt;
&lt;br /&gt;
3) '''PCP[0, log(n)] = [[P|P]]''' (логарифмическое число обращений к строке &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; также не помогают, так как можно аналогичным образом перебрать всевозможные результаты обращений за полиномиальное время)&lt;br /&gt;
&lt;br /&gt;
4) '''PCP[poly(n), 0] = [[Сложностные_классы_RP_и_coRP|coRP]]''' (по определению '''coRP''')&lt;br /&gt;
&lt;br /&gt;
5) '''PCP[0, poly(n)] = [[NP|NP]]''' (по определению '''NP''' на языке сертификатов)&lt;br /&gt;
&lt;br /&gt;
6) '''PCP[log(n), O(1)] = [[NP|NP]]''' ([[PCP-теорема]])&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8_(%D1%81%D1%82%D0%B0%D1%80%D0%B0%D1%8F_%D1%82%D1%80%D0%B5%D1%88%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%8F)&amp;diff=1295</id>
		<title>Теория сложности (старая трешовая версия)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8_(%D1%81%D1%82%D0%B0%D1%80%D0%B0%D1%8F_%D1%82%D1%80%D0%B5%D1%88%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%8F)&amp;diff=1295"/>
				<updated>2010-05-30T09:57:45Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Лекция 1 ==&lt;br /&gt;
*[[Класс DSPACE]]&lt;br /&gt;
*[[Класс DTIME]]&lt;br /&gt;
*[[Теорема о емкостной иерархии]]&lt;br /&gt;
*[[Теорема о временной иерархии]]&lt;br /&gt;
*[[Сведение по Карпу]]&lt;br /&gt;
*[[Сведение по Куку]]&lt;br /&gt;
*[[Класс P]]&lt;br /&gt;
*[[Класс NP]]&lt;br /&gt;
*[[Класс coNP]]&lt;br /&gt;
&lt;br /&gt;
== Практика 1 ==&lt;br /&gt;
*[[Сведение по Куку задачи факторизации к языку из NP]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 2 ==&lt;br /&gt;
*[[Теорема Кука]]&lt;br /&gt;
&lt;br /&gt;
== Практика 2 ==&lt;br /&gt;
*[[Понятие NP-трудной и NP-полной задачи]]&lt;br /&gt;
*[[NP-полнота задачи BH1N]]&lt;br /&gt;
*[[NP-полнота задачи о выполнимости булевой формулы в форме КНФ]]&lt;br /&gt;
*[[NP-полнота задачи о выполнимости булевой формулы в форме 3-КНФ]]&lt;br /&gt;
*[[NP-полнота задачи о клике]]&lt;br /&gt;
*[[NP-полнота задачи о независимом множестве]]&lt;br /&gt;
*[[NP-полнота задачи о вершинном покрытии]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 3 ==&lt;br /&gt;
*[[Теорема Ладнера]]&lt;br /&gt;
*[[Теорема Левина]]&lt;br /&gt;
*[[Теорема Бейкера-Гилла-Соловэя]]&lt;br /&gt;
&lt;br /&gt;
== Практика 3 ==&lt;br /&gt;
*[[NP-полнота задач о гамильтоновом цикле и пути в графах]]&lt;br /&gt;
*[[NP-полнота задачи о сумме подмножества]]&lt;br /&gt;
*[[NP-полнота задачи о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
== Практика, которой на самом деле не было ==&lt;br /&gt;
*[[NP-полнота задачи о раскраске графа]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 4 ==&lt;br /&gt;
*[[Класс PS]]&lt;br /&gt;
*[[Теорема Сэвича]]&lt;br /&gt;
*[[PS-полнота задачи Generalized geography]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 6 ==&lt;br /&gt;
*Классы [[L]], [[NL]], [[NL-полнота|NLC]]&lt;br /&gt;
*[[NL-полнота задачи о достижимости в графе]]&lt;br /&gt;
*[[Классы EXP, NEXP. Полнота языков EXP и NEXP]]&lt;br /&gt;
*[[Теорема о связи вопросов EXP=NEXP и P=NP]]&lt;br /&gt;
*[[Теорема Иммермана]]&lt;br /&gt;
&lt;br /&gt;
== Практика 6 ==&lt;br /&gt;
*[[Классы Sigma_i и Pi_i]]&lt;br /&gt;
*[[Класс PH]]&lt;br /&gt;
*[[Полиномиальная иерархия]]&lt;br /&gt;
*[[Теоремы о коллапсе полиномиальной иерархии]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 7 ==&lt;br /&gt;
*[[Теорема Карпа-Липтона]]&lt;br /&gt;
&lt;br /&gt;
== Практика 7 ==&lt;br /&gt;
*[[Вероятностная машина Тьюринга]]&lt;br /&gt;
*[[Класс ZPP]]&lt;br /&gt;
*[[Сложностные классы RP и coRP]]&lt;br /&gt;
*[[Сложностный класс PP]]&lt;br /&gt;
*[[Сложностный класс BPP]]&lt;br /&gt;
*[[Уменьшение ошибки в классе RP, сильное и слабое определение]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 8 ==&lt;br /&gt;
*[[Теорема о включении BPP в P/poly]]&lt;br /&gt;
*[[Теорема Лаутемана]]&lt;br /&gt;
*[[Теорема Валианта-Вазирани]]&lt;br /&gt;
&lt;br /&gt;
== Практика 8 ==&lt;br /&gt;
*[[Лемма Шварца-Зиппеля]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 9 ==&lt;br /&gt;
*[[Класс IP|Класс IP]]&lt;br /&gt;
*[[GNI|Принадлежность проблемы GNI классу IP]]&lt;br /&gt;
*[[Sharp SAT|#SAT]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 10 ==&lt;br /&gt;
*[[Теорема Шамира]]&lt;br /&gt;
*[[Семейство универсальных попарно независимых хеш-функций|Семейство универсальных попарно независимых хеш-функций]]&lt;br /&gt;
*[[Теорема Голдвассера, Сипсера]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 11 ==&lt;br /&gt;
*[[Абсолютная секретность]]&lt;br /&gt;
*[[Лемма о невозможности существования вычислительно безопасных шифров в случае P = NP]]&lt;br /&gt;
*[[Односторонние функции и псевдослучайные генераторы]]&lt;br /&gt;
*[[Доказательства с нулевым разглашением]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 12 ==&lt;br /&gt;
*[[Кубит]]&lt;br /&gt;
*[[Унитарные операторы]]&lt;br /&gt;
*[[Квантовый логический элемент NOT]]&lt;br /&gt;
*[[Преобразование Адамара]]&lt;br /&gt;
*[[Квантовый логический элемент CNOT]]&lt;br /&gt;
*[[Квантовый логический элемент Тоффоли]]&lt;br /&gt;
*[[Квантовая схема]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 13 ==&lt;br /&gt;
*[[Класс PCP]]&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=NL-%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%B4%D0%BE%D1%81%D1%82%D0%B8%D0%B6%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5&amp;diff=687</id>
		<title>NL-полнота задачи о достижимости в графе</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=NL-%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%B4%D0%BE%D1%81%D1%82%D0%B8%D0%B6%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5&amp;diff=687"/>
				<updated>2010-04-06T11:48:20Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Формулировка задачи==&lt;br /&gt;
Даны ориентированный граф &amp;lt;tex&amp;gt; G = \langle V, E \rangle &amp;lt;/tex&amp;gt; и две вершины &amp;lt;tex&amp;gt; s, t&amp;lt;/tex&amp;gt; в нем. Необходимо проверить, правда ли, что в графе &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; существует путь из вершины &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt; t &amp;lt;/tex&amp;gt;. Эту задачу принято называть &amp;lt;tex&amp;gt; st-connectivity &amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt; STCON &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Утверждение ==&lt;br /&gt;
Задача &amp;lt;tex&amp;gt; STCON &amp;lt;/tex&amp;gt; [[NL-полнота|NL-полна]].&lt;br /&gt;
&lt;br /&gt;
== Доказательство ==&lt;br /&gt;
Для доказательства [[NL-полнота|NL-полноты]] необходимо показать, что эта задача NL-трудная и принадлежит [[NL|классу NL]].&lt;br /&gt;
&lt;br /&gt;
=== Доказательство принадлежности задачи STCON классу NL ===&lt;br /&gt;
&lt;br /&gt;
Для доказательства необходимо предъявить алгоритм для недетерминированной машины Тьюринга, который использует конечное число переменных, каждая из которых занимает &amp;lt;tex&amp;gt; O(log n) &amp;lt;/tex&amp;gt; памяти, где &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; - размер входа для задачи и за время порядка &amp;lt;tex&amp;gt; O(poly(n)) &amp;lt;/tex&amp;gt; решает эту задачу.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
1. Начиная с вершины &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; недетерминированно переходит в одну из вершин, смежных с ней. (Очевидно, для этого необходимо конечное число переменных)&lt;br /&gt;
&lt;br /&gt;
2. Проверяет, правда ли, что текущая вершина совпадает с &amp;lt;tex&amp;gt; t &amp;lt;/tex&amp;gt;. Если это так, возвращает TRUE.&lt;br /&gt;
&lt;br /&gt;
3. Отдельно считает количество пройденных вершин. Как только это число превышает количество вершин в графе, то алгоритм возвращает FALSE, так как посетил некоторую вершину дважды.&lt;br /&gt;
&lt;br /&gt;
Таким образом в каждый момент алгоритму достаточно хранить текущую вершину, количество посещенных вершин, финальную вершину &amp;lt;tex&amp;gt; t &amp;lt;/tex&amp;gt; и некоторое число вспомогательных переменных, для совершения переходов. Все эти переменные принимают значения не более, чем максимальный номер вершины, то есть как раз занимают &amp;lt;tex&amp;gt; O(log n) &amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
&lt;br /&gt;
Так как, если из &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; существует путь в &amp;lt;tex&amp;gt; t &amp;lt;/tex&amp;gt;, то он имеет длину не более, чем количество вершин в графе, то алгоритм корректно возвращает FALSE.&lt;br /&gt;
&lt;br /&gt;
=== Доказательство NL-трудности задачи STCON ===&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=NL-%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%B4%D0%BE%D1%81%D1%82%D0%B8%D0%B6%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5&amp;diff=676</id>
		<title>NL-полнота задачи о достижимости в графе</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=NL-%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%B4%D0%BE%D1%81%D1%82%D0%B8%D0%B6%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5&amp;diff=676"/>
				<updated>2010-04-06T10:58:06Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Формулировка задачи==&lt;br /&gt;
Даны ориентированный граф &amp;lt;tex&amp;gt; G = \langle V, E \rangle &amp;lt;/tex&amp;gt; и две вершины &amp;lt;tex&amp;gt; s, t&amp;lt;/tex&amp;gt; в нем. Необходимо проверить, правда ли, что в графе &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; существует путь из вершины &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt; t &amp;lt;/tex&amp;gt;. Эту задачу принято называть &amp;lt;tex&amp;gt; st-connectivity &amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt; STCON &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Утверждение ==&lt;br /&gt;
Задача &amp;lt;tex&amp;gt; STCON &amp;lt;/tex&amp;gt; [[NL-полнота|NL-полна]].&lt;br /&gt;
&lt;br /&gt;
== Доказательство ==&lt;br /&gt;
Для доказательства [[NL-полнота|NL-полноты]] необходимо показать, что эта задача NL-трудная и принадлежит [[NL|классу NL]].&lt;br /&gt;
&lt;br /&gt;
=== Доказательство принадлежности задачи STCON классу NL ===&lt;br /&gt;
&lt;br /&gt;
=== Доказательство NL-трудности задачи STCON ===&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=NL-%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%B4%D0%BE%D1%81%D1%82%D0%B8%D0%B6%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5&amp;diff=674</id>
		<title>NL-полнота задачи о достижимости в графе</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=NL-%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%B4%D0%BE%D1%81%D1%82%D0%B8%D0%B6%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5&amp;diff=674"/>
				<updated>2010-04-06T10:29:04Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: Новая страница: «== Формулировка задачи== Даны ориентированный граф &amp;lt;tex&amp;gt; G = \langle V, E \rangle &amp;lt;/tex&amp;gt; и две вершины &amp;lt;tex&amp;gt; s, t…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Формулировка задачи==&lt;br /&gt;
Даны ориентированный граф &amp;lt;tex&amp;gt; G = \langle V, E \rangle &amp;lt;/tex&amp;gt; и две вершины &amp;lt;tex&amp;gt; s, t&amp;lt;/tex&amp;gt; в нем. Необходимо проверить, правда ли, что в графе &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; существует путь из вершины &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt; t &amp;lt;/tex&amp;gt;. Эту задачу принято называть &amp;lt;tex&amp;gt; REACH &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Утверждение ==&lt;br /&gt;
Задача &amp;lt;tex&amp;gt; REACH &amp;lt;/tex&amp;gt; [[NL-полнота|NL-полна]].&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8_(%D1%81%D1%82%D0%B0%D1%80%D0%B0%D1%8F_%D1%82%D1%80%D0%B5%D1%88%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%8F)&amp;diff=673</id>
		<title>Теория сложности (старая трешовая версия)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8_(%D1%81%D1%82%D0%B0%D1%80%D0%B0%D1%8F_%D1%82%D1%80%D0%B5%D1%88%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%8F)&amp;diff=673"/>
				<updated>2010-04-06T10:24:21Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Лекция 1 ==&lt;br /&gt;
*[[Класс DSPACE]]&lt;br /&gt;
*[[Класс DTIME]]&lt;br /&gt;
*[[Теорема о емкостной иерархии]]&lt;br /&gt;
*[[Теорема о временной иерархии]]&lt;br /&gt;
*[[Сведение по Карпу]]&lt;br /&gt;
*[[Сведение по Куку]]&lt;br /&gt;
*[[Класс P]]&lt;br /&gt;
*[[Класс NP]]&lt;br /&gt;
*[[Класс coNP]]&lt;br /&gt;
&lt;br /&gt;
== Практика 1 ==&lt;br /&gt;
*[[Сведение по Куку задачи факторизации к языку из NP]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 2 ==&lt;br /&gt;
*[[Теорема Кука]]&lt;br /&gt;
&lt;br /&gt;
== Практика 2 ==&lt;br /&gt;
*[[Понятие NP-трудной и NP-полной задачи]]&lt;br /&gt;
*[[NP-полнота задачи BH1N]]&lt;br /&gt;
*[[NP-полнота задачи о выполнимости булевой формулы в форме КНФ]]&lt;br /&gt;
*[[NP-полнота задачи о выполнимости булевой формулы в форме 3-КНФ]]&lt;br /&gt;
*[[NP-полнота задачи о клике]]&lt;br /&gt;
*[[NP-полнота задачи о независимом множестве]]&lt;br /&gt;
*[[NP-полнота задачи о вершинном покрытии]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 3 ==&lt;br /&gt;
*[[Теорема Ладнера]]&lt;br /&gt;
*[[Теорема Левина]]&lt;br /&gt;
*[[Теорема Бейкера-Гилла-Соловэя]]&lt;br /&gt;
&lt;br /&gt;
== Практика 3 ==&lt;br /&gt;
*[[NP-полнота задач о гамильтоновом цикле и пути в графах]]&lt;br /&gt;
*[[NP-полнота задачи о сумме подмножества]]&lt;br /&gt;
*[[NP-полнота задачи о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
== Практика, которой на самом деле не было ==&lt;br /&gt;
*[[NP-полнота задачи о раскраске графа]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 4 ==&lt;br /&gt;
*[[Класс PS]]&lt;br /&gt;
*[[Теорема Сэвича]]&lt;br /&gt;
*[[PS-полнота задачи Generalized geography]]&lt;br /&gt;
&lt;br /&gt;
== Лекция 6 ==&lt;br /&gt;
*[[NL-полнота задачи о достижимости в графе]]&lt;br /&gt;
*[[Теорема о связи вопросов EXP=NEXP и P=NP]]&lt;br /&gt;
&lt;br /&gt;
== Практика 6 ==&lt;br /&gt;
*[[Классы Sigma_i и Pi_i]]&lt;br /&gt;
*[[Класс PH]]&lt;br /&gt;
*[[Полиномиальная иерархия]]&lt;br /&gt;
*[[Теоремы о коллапсе полиномиальной иерархии]]&lt;br /&gt;
&lt;br /&gt;
== Практика 7 ==&lt;br /&gt;
*[[Класс BPP]]&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%BE_%D1%91%D0%BC%D0%BA%D0%BE%D1%81%D1%82%D0%BD%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D0%B8&amp;diff=583</id>
		<title>Теорема о ёмкостной иерархии</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%BE_%D1%91%D0%BC%D0%BA%D0%BE%D1%81%D1%82%D0%BD%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D0%B8&amp;diff=583"/>
				<updated>2010-03-23T14:35:00Z</updated>
		
		<summary type="html">&lt;p&gt;Joshik: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Формулировка ==&lt;br /&gt;
'''Теорема о емкостной иерархии''' утверждает, что для любых двух [[Конструируемая по памяти функция|конструируемых по памяти функций]] &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; таких, что &amp;lt;tex&amp;gt; \lim \limits_{n \rightarrow \infty} f(n)/g(n) = 0&amp;lt;/tex&amp;gt;, выполняется &amp;lt;tex&amp;gt;DSPACE(g(n)) \ne DSPACE(f(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство ==&lt;br /&gt;
Зафиксируем функции &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим язык &amp;lt;tex&amp;gt;L = \{ \langle m,x \rangle \mid m(\langle m,x \rangle )&amp;lt;/tex&amp;gt; не допускает, используя не более &amp;lt;tex&amp;gt; f(|\langle m,x\rangle|)&amp;lt;/tex&amp;gt; памяти &amp;lt;tex&amp;gt;\}&amp;lt;/tex&amp;gt; и докажем, что &amp;lt;tex&amp;gt;L \notin DSPACE(f)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;L \in DSPACE(g)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Допустим, что &amp;lt;tex&amp;gt;L \in DSPACE(f)&amp;lt;/tex&amp;gt;, тогда существует детерминированная машина Тьюринга &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;L(m_0)=L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим выход машины &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt; на входе &amp;lt;tex&amp;gt;\langle m_0,x\rangle&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt; допускает &amp;lt;tex&amp;gt;\langle m_0,x\rangle&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\langle m_0,x\rangle \in L&amp;lt;/tex&amp;gt;, но в  &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; по определению не может быть пары &amp;lt;tex&amp;gt;\langle m,x\rangle&amp;lt;/tex&amp;gt;, которую допускает &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;. Таким образом, &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt; не может допускать &amp;lt;tex&amp;gt;\langle m_0,x\rangle&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt; не допускает &amp;lt;tex&amp;gt;\langle m_0,x\rangle&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\langle m_0,x\rangle&amp;lt;/tex&amp;gt; не принадлежит языку &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Из определения это значит, что либо &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt; допускает &amp;lt;tex&amp;gt;\langle m_0,x\rangle&amp;lt;/tex&amp;gt;, либо не допускает, используя памяти больше &amp;lt;tex&amp;gt;f(|\langle m_0,x\rangle|)&amp;lt;/tex&amp;gt;. Но &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt; выбрана таким образом, что на любом входе &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; она использует не более &amp;lt;tex&amp;gt;f(|x|)&amp;lt;/tex&amp;gt; памяти. Получаем противоречие.&lt;br /&gt;
&lt;br /&gt;
Следовательно, такой машины не существует. Таким образом, &amp;lt;tex&amp;gt;L \notin DSPACE(f)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;L \in DSPACE(g)&amp;lt;/tex&amp;gt;, так как языку &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; можно сопоставить машину Тьюринга &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt;, распознающую &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и такую, что на любом входе  &amp;lt;tex&amp;gt;\langle m_1,x\rangle \in L&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt; будет работать аналогично &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; завершила работу, используя не более &amp;lt;tex&amp;gt;f(|\langle m_1,x\rangle|)&amp;lt;/tex&amp;gt; памяти, и не допустила, то &amp;lt;tex&amp;gt;m_0&amp;lt;/tex&amp;gt; допускает &amp;lt;tex&amp;gt;\langle m_1,x\rangle&amp;lt;/tex&amp;gt;. В другом случае не допускает. Любая такая машина использует памяти не более &amp;lt;tex&amp;gt;f(|\langle m_1,x\rangle|)&amp;lt;/tex&amp;gt;. По условию теоремы &amp;lt;tex&amp;gt;\lim \limits_{n \rightarrow \infty} f(n)/g(n) = 0&amp;lt;/tex&amp;gt;, поэтому начиная с некоторого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; будет использовать памяти не более &amp;lt;tex&amp;gt;g(|\langle m_1,x\rangle|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом получили, что &amp;lt;tex&amp;gt;L \in DSPACE(g(n)) \setminus DSPACE(f(n))&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;DSPACE(g(n)) \neq DSPACE(f(n))&amp;lt;/tex&amp;gt;, что и требовалось доказать.&lt;/div&gt;</summary>
		<author><name>Joshik</name></author>	</entry>

	</feed>