Алгоритмы точного вычисления гиперобъема

Материал из Викиконспекты
Перейти к: навигация, поиск
Эта статья находится в разработке!

Постановка задачи

[math]x = (x_1, x_2, ..., x_d; x_i \ge 0) \in R^d[/math] - точка в [math]d[/math]-мерном пространстве.

Точка [math]x[/math] доминирует точку [math]y[/math] ([math]x \succ y[/math]), если [math]\forall i : x_i \ge y_i, \exists j : x_j \gt y_j[/math].

[math]X = (x^1, x^2, ..., x^n) \subset R^d[/math] - множество из [math]n[/math] точек в [math]d[/math]-мерном пространстве таких, что [math]\nexists i \neq j : x_i \succ x_j[/math] - никакая точка не доминируется другой точкой из этого множества.

[math]S(X) = \mu (\bigcup \limits_{x \in X} \{y | y \succ x\}) [/math] - гиперобъем множества [math]X[/math].

В частности, если [math]X = \{x\}[/math], то [math]S(X) = \prod \limits_{i=1}^{d} x_i[/math].

Задача: найти точное значение гиперобъема [math]S(X)[/math] множества из [math]n[/math] точек [math]d[/math]-мерного пространоства.

Алгоритм включения-исключения (Inclusion-Exclusion Algorithm, IEA)

Самый простой алгоритм нахождения гиперобъема базируется на идее комбинаторной формулы включения-искючения. Все множество [math]X[/math] представляется в виде объединения [math]n[/math] гиперкубов ([math]X^i[/math]), соответствующих отдельным точкам [math]x^i[/math].

После этого объем всего множества вычисляется по формуле:
[math] S(X) = \sum \limits_{I \in 2^n} (-1)^{|I|+1} S(\bigcap \limits_{ j \in I} X^j) [/math]

Объем пересечения гиперкубов легко считается как произведение по каждой координате минимального значения этой координаты среди всех точек, которым соответствуют гиперкубы.

Таким образом, в этом алгоритме перебираются все подмножества точек множества [math]X[/math], для каждого множества находится гиперобъем пересечения соответствующих гиперкубов и он прибавляется с соответствующим знаком к ответу. Время работы этого алгоритма составляет [math]O(n 2^n)[/math].

Алгоритм LebMeasure

Алгоритм LebMeasure обрабатывает точки множества [math]X[/math] по очереди. Для каждой очередной точки [math]x[/math] находится объем некоторого максимального по включению гиперкуба, доминируемого эксклюзивно только этой точкой [math]x[/math] и она заменяется на некоторое множество порожденных точек, которые доминируют оставшуюся область, доминировшуюся до этого точкой [math]x[/math].

Например, если изначально было четыре точки в трехмерном пространстве
[math](6, 7, 4), (9, 5, 5), (1, 9, 3), (4, 1, 9)[/math],
то точка [math](6, 7, 4)[/math] эксклюзивно доминирует куб с одним концов в [math](6, 7, 4)[/math], а другим - в [math](4, 5, 3)[/math]. После добавления объема этого куба в ответу, точка [math](6, 7, 4)[/math] порождает три точки:
[math](4, 7, 4), (6, 5, 3), (6, 7, 3)[/math].
При этом, точка [math](6, 5, 4)[/math] доминируется точкой [math](9, 5, 5)[/math] и сразу удаляется из множества [math]X[/math].

Обработка точек продолжается, пока все точки не будут обработаны. Таким образом, время работы алгоритмы напрямую зависит от количества порожденных точек. Легко заметить, что таких точек не более, чем [math]n^d[/math], поскольку каждая координата каждой порожденной точки равна соответствующей координате некоторой точки исходного множества [math]X[/math].

К сожалению, эта верхняя оценка является достижимой. Например, если исходное множество [math]X[/math] имеет вид: [math](1, n, n, ..., n), (2, n - 1, n - 1, ..., n - 1), ..., (n, 1, 1, ..., 1)[/math], и точки обрабатываются в этом порядке, то всего будет обработано [math]n^{d-1}[/math] точка, что показано в [1]. Правда, если в этом примере точки обрабатываются в обратном порядке, то суммарное количество обработанных точек линейно зависит от [math]n[/math] и [math]d[/math]. Тем не менее, существуют примеры, для которых любой порядок обработки приводит к экспоненциальной зависимости числа порожденных точек от размерности пространства [math]d[/math] и близок к [math]n^d[/math] [1].

Алгоритм Hypervolume by Slicing Objectives (HSO)

Под Objectives в названии данного алгоритма имеются в виду координаты пространства [math]R^d[/math].

Если алгоритм LebMeasure по очереди рассматривает все точки, то алгоритм HSO рассматривает по очереди все координаты, сводя задачу к меньшей на единицу размерности.

Изначально все точки сортируются по первой координате. Значения этой координаты используются для расслоения(разрезания) всего множества на [math]n[/math] частей, внутри каждой из которых при движении вдоль первой координаты форма разреза перпендикулярно оси первой координаты не меняется. Таким образом, для подсчета объема каждой части необходимо найти объем разреза и умножить длину части вдоль первой координаты. При этом получившийся разрез имеет на единицу меньшую размерность. Заметим, что после сортировки и расслоения первая часть содержит все [math]n[/math] точек, вторая - все, помимо точки с минимальной координатой, вдоль которой происходит расслоение и т.д., а последняя часть содержит только одну точку с максимальной этой координатой.

После этого все полученные части расслаиваются уже по второй координате, далее все полученные - по третьей и т.д. В итоге исходное множество разбивается на несколько непересекающихся гиперкубов и остается найти суммарный гиперобъем. Заметим, что расслаивание части можно прекратить в тот момент, когда в нее входит только одна точка и посчитать объем гиперкуба, образованного проекцией этой точки на оставшиеся координаты.

Описанный процесс можно реализовать как в виде рекурсивной процедуры, расслаивающей множество вдоль очередной координаты и вызывающей себя рекурсивно для каждой части и следующей координаты, так и нерекурсивно, если поддерживать множество всех текущих частей и на очередной итерации разбивать их все вдоль очередной координаты.

Время работы алгоритма напрямую зависит от суммарного количества частей, на которые будет разбито исходное множество. По аналогичным предыдущему алгоритму рассуждениям легко показывается, что частей не более [math]n^d[/math]. Тем не менее, существует более точная оценка.

Теорема:
Суммарное количество частей, полученных алгоритмом HSO, не превышает
[math]f(n, d) = {n + d - 2 \choose d - 1}[/math].
Доказательство:
[math]\triangleright[/math]
База:
[math]f(n, 1) = 1[/math].
Также, из алгоритма расслоения следует, что из части с [math]n[/math] точками будет получено по одной части для каждого [math]i = 1...n[/math], то есть:
[math]f(n, d) = \sum \limits_{i = 1}^{n}f(i, d - 1)[/math].

Докажем полезные леммы:

Лемма:
[math]{x \choose y} = {x - r \choose y} + \sum \limits_{i = 1}{r} {x - i \choose y - 1}[/math].
Доказательство:
[math]\triangleright[/math]
Индукция по [math]r[/math]. База:
[math]{x \choose y} = {x - 1 \choose y} + {x - 1 \choose y - 1}[/math].
[math]\triangleleft[/math]
2)
[math]\triangleleft[/math]

Таким образом, на этот алгоритм получена более низкая оценка времени работы, чем на предыдущий, и это подтверждается на практике [1].

Сведение к задаче KMP (Klee's Measure Problem)

Задача KMP состоит в нахождении объема объединения прямоугольных гиперпараллелепипедов в [math]d[/math]-мерном пространстве. Как показано в описании алгоритма IEA, исходная задача легко сводится к этой, если каждой точке поставить в соответствие гиперкуб с одной вершиной в центре координат, а противоположной - в этой точке.

Существует несколько алгоритмов решения задачи KMP, самый оптимальный из которых использует идеи сканирующей гиперплоскости, корневой эвристики и КД-дерево, и позволяет решать задачу за время [math]O(n^{d/2}\log n)[/math]. Рассмотрим его.

Для начала изложим идею сканирующей гиперплоскости. Рассмотрим всевозможные значения [math]d[/math]-ой координаты у точек множества [math]X[/math]. Возьмем гиперплоскость, перпендикулярную оси [math]d[/math]-ой координаты, будем ее двигать по этим значениям от минимального до максимального и рассматривать проекцию всех гиперкубов на эту гиперплоскость. Заметим, что между точками проекция меняться не будет, а в каждой точке будут появляться или исчезать проекции некоторых гиперкубов. Поэтому, если уметь эффективно пересчитывать объем проекции при каждом появлении/исчезновении и прибавлять это значение, умноженное на расстояние между последовательными значениями [math]d[/math]-ой координаты, то можно легко посчитать суммарный гиперобъем. Как раз для эффективного пересчета используется такая структура, как КД-дерево.

Теперь изложим идею алгоритма на примере трехмерного пространства. Будем считать, что сканирующая плоскость двигается перепендикулярно оси [math]OZ[/math]. В каждый момент проекция всех параллелепипедов на эту плоскость предствляет собой множество прямоугольников и необходимо уметь обрабатывать следующие три запроса:

  1. добавить прямоугольник
  2. удалить прямоугольник
  3. посчитать площадь объединения всех прямоугольников


Определение:
КД-деревом называется сбалансированное двоичное дерево, где каждой вершине [math]\alpha[/math] соответствует некоторая область [math]C_{\alpha}[/math] [math]d[/math]-мерного пространстве, удовлетворяющая следующим свойствам:
  1. Корневой вершине [math]root[/math] соответствует [math]C_{root}[/math] - все пространство.
  2. Каждое [math]C_{\alpha}[/math] является гиперпараллелепипедом (возможно бесконечным в некоторых направлениях).
  3. Для каждой вершины [math]\alpha[/math] с детьми [math]\beta[/math] и [math]\gamma[/math] верно, что области [math]C_{\beta}[/math] и [math]C_{\gamma}[/math] не пересекаются и [math]C_{\alpha} = C_{\beta} \cup C_{\gamma}[/math].


Будем хранить прямоугольники в КД-дереве следующим образом:

  1. Для каждого листа [math]\alpha[/math] будем хранить все прямоугольники, которые пересекают внутреннюю часть области [math]C_{\alpha}[/math].
  2. Для каждой внутренней вершины [math]\alpha[/math] будем считать число [math]Cover_{\alpha}[/math] - количество прямоугольников, которые полностью покрывают область [math]C_{\alpha}[/math], но не полностью покрывают область родителя этой вершины [math]C_{father(\alpha)}[/math].

Также для каждой вершины будем хранить значение площади пересечения области этой вершины со всеми прямоугольниками [math]M[/math], которое определяется следующим образом:

  1. Для каждого листа [math]M[/math] равно площади пересечения всех прямоугольников с областью этого листа.
  2. Для каждой внутренней вершины [math]\alpha[/math] если [math]Cover_{\alpha} \gt 0[/math], тогда [math]M[/math] равно площади всех области [math]C_{\alpha}[/math], иначе [math]M[/math] равно сумме этих значений для двух сыновей этой вершины.

Таким образом, значение для корневой вершины [math]M_{root}[/math] и является искомой площадью объединения всех прямоугольников.

Рассмотрим операцию добавления прямоугольника (box) в КД-дерево.

 procedure Insert(box, [math]\alpha[/math])
 if [math]\alpha[/math] - лист then
   добавить box в эту вершину
   пересчитать [math]M_{\alpha}[/math]
 elseif box покрывает область [math]C_{\alpha}[/math] then
   [math]Cover_{\alpha} = Cover_{\alpha} + 1[/math]
   [math]M_{\alpha} = [/math] объем области [math]C_{\alpha}[/math]
 elseif box пересекает область [math]C_{\alpha}[/math] then
   Insert(box, leftson([math]\alpha[/math]))
   Insert(box, rightson([math]\alpha[/math]))
   if [math]Cover_{\alpha} \gt  0 [/math] then
     [math]M_{\alpha} = [/math] объем области [math]C_{\alpha}[/math]
   else
     [math]M_{\alpha} = M_{leftson(\alpha)} + M_{rightson(\alpha)}[/math]

Аналогично устроена операция удаления прямоугольника - она выполняет обратные действия.

Рассмотрим теперь как именно будет устроено разделение пространства на области КД-деревом для эффективного его использования. Возьмем проекции всех параллелепипедов на плоскость, перепендикулярную оси [math]OZ[/math] - множество прямоугольников [math]V[/math]. Рассмотрим все [math]x[/math]-координаты границ прямоугольников и разобьем ось [math]OX[/math] на [math]2\sqrt{n}[/math] промежутков так, чтобы в каждом из них было не более [math]\sqrt{n}[/math] границ. Получившиемя [math]2\sqrt{n}[/math] полос разобьем горизонтальными линиями на итоговые области по отдельности следующим образом. Для каждой полосы у всех прямоугольников, имеющих вертикальную границу в этой полосе возьмем все горизонтальные границы (их будет не более [math]2\sqrt{n}[/math]), а среди всех горизонтальных границ, пересекающих область, возьмем каждую [math]\sqrt{n}[/math]-ую. Таким образом, в итоге получим не более [math]4\sqrt{n}[/math] областей в каждой верикальной полосе.

Полученные области обладают следующими свойствами:

  1. Всего [math]O(n)[/math] областей.
  2. Каждый прямоугольник частично покрывает не более [math]O(\sqrt{n})[/math] областей.
  3. Никакая вершина прямоугольника не лежит внутри какой-нибудь области.
  4. Для каждой области есть не более [math]O(\sqrt{n})[/math] частично покрывающих ее прямоугольников.

Все эти утверждения несложно следуют из алгоритма разбиения на области.

Каждая из этих областей будет одним из листов КД-дерева. Для построения всего дерева сначала объединим все области для одной вертикальной полосы, сливая соседние области в одну вершину. После этого аналогично будем сливать соседние вертикальные области и в итоге получим корневую вершину, представляющую всю плоскость.

Построенное КД-дерево обладает следующими свойствами:

  1. В нем [math]O(n)[/math] вершин.
  2. Каждый прямоугольник хранится в [math]O(\sqrt{n})[/math] листьях.
  3. Каждый прямоугольник влияет на [math]O(\sqrt{n} \log n)[/math] значений [math]Cover[/math].
  4. Никакая вершина прямоугольника не лежит внутри области какого-нибудь листа.
  5. Для области каждого листа есть не более [math]O(\sqrt{n})[/math] частично покрывающих ее прямоугольников.

Все эти свойства следуют из свойств разбиения на области и логарифмической высоты дерева.

Наконец, получаем итоговый алгоритм. Идем сканирующей плоскостью, перепендикулярной оси [math]OZ[/math], добавляя или удаляя прямоугольники из КД-дерева. При этом каждый раз пересчитывается площадь объединения всех текущих прямоугольников и, складывая эти величины, умноженные на соответствующую разницу [math]z[/math]-координат получаем общий объем.

Каждая операция добавления или удаления прямоугольников требует изменения [math]O(\sqrt{n} \log n)[/math] полей [math]Cover[/math], а также операций добавления или удаления прямоугольника в [math]O(\sqrt{n})[/math] листьев, каждая из которых требует [math]O(\log n)[/math] времени. Итого, на одну операцию добавления или удаления требуется [math]O(\sqrt{n} \log n)[/math] времени, суммарно таких операций [math]O(n)[/math], и получается, что весь алгоритм работает за [math]O(n \sqrt{n} \log n)[/math]. При этом на хранение всей информации требуется [math]O(n\sqrt{n}) [/math] памяти - каждый лист может хранить [math]O(\sqrt{n})[/math] прямоугольников.

Все идеи этого алгоритма обобщаются с трехмерного пространства на [math]d[/math]-мерное следующим образом.

Построение разбиения на области в [math]d[/math]-мерном пространстве вместо двухмерного ведется сначала аналогичным образом, только после того, как в двухмерном пространстве получаются итоговые прямоугольные области, здесь продолжаются аналогичные разбиения вдоль третьей координаты - берутся все границы третьей координаты гиперпараллелепипедов, имеющие границу по первой или второй координате строго внутри области (их получается не более [math]O(\sqrt{n})[/math]), а также каждую [math]O(\sqrt{n})[/math]-ую границу по третьей координате гиперепараллелепипедов, пересекающих эту область, и так далее.

Это разбиение на области имеет следующие аналогичные свойства:

  1. Всего [math]O(n^{d/2})[/math] областей.
  2. Каждый гиперпараллелепипед частично покрывает не более [math]O(n^{(d-1)/2})[/math] областей.
  3. Никакая вершина гиперпараллелепипеда не лежит внутри какой-нибудь области.
  4. Для каждой области есть не более [math]O(\sqrt{n})[/math] частично покрывающих ее гиперпараллелепипедов.

Общее дерево строится аналогичным образом и оно в итоге состоит из [math]d[/math] уровней, каждый из которых имеет высоту [math]O(\log n)[/math] в дереве - самый верхний уровень содержит разбиение по первой координате, следующий - по второй и так далее.

Построенное КД-дерево обладает следующими свойствами:

  1. В нем [math]O(n^{d/2})[/math] вершин.
  2. Каждый гиперпараллелепипед хранится в [math]O(n^{(d-1)/2})[/math] листьях.
  3. Каждый гиперпараллелепипед влияет на [math]O(n^{(d-1)/2} \log n)[/math] значений [math]Cover[/math].
  4. Никакая вершина гиперпараллелепипеда не лежит внутри области какого-нибудь листа.
  5. Для области каждого листа есть не более [math]O(\sqrt{n})[/math] частично покрывающих ее гиперпараллелепипедов.

Операции в этом дереве выполняются аналогично трехмерному случаю и каждая операция добавления или удаления в КД-дерево размерности [math]d[/math] занимает [math]O(n^{(d-1)/2} \log n)[/math] времени. Выполняя сканирование гиперплоскостью вдоль одной из координат получаем КД-дерево размерности [math]d-1[/math], в котором необходимо провести [math]O(n)[/math] операций, то есть суммарное время работы алгоритма равно: [math]O(n \times n^{(d-1-1)/2} \log n) = O(n^{d/2} \log n)[/math]. При этом хранение КД-дерева требует [math]O(n^{d/2})[/math] памяти.

Источники

  1. 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)
  2. 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)
  3. K. Bringmann, T. Friedrich.: An Efficient Algorithm for Computing Hypervolume Contributions. Evolutionary Computation, Vol. 18, No. 3, pp 383-402, MIT Press. (2010)
  4. N. Beume.: S-Metric calculation by considering dominated hypervolume as Klee’s measure problem. Evolutionary Computation, 17(4), pp 477–492. (2009)
  5. 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)
  6. Overmars, M.H., Yap, C.K.: New upper bounds in Klee’s measure problem. SIAM Journal on Computing 20(6), pp 1034–1045. (1991)
  7. 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)