Учитывая набор прямоугольников, найдите 3 ограничивающих прямоугольника с наименьшей площадью - PullRequest
6 голосов
/ 20 февраля 2011

Я пытаюсь реализовать области перерисовки, содержащие до 3 областей, но не могу придумать эффективный способ найти лучший набор областей по набору прямоугольников.

Таким образом, будет набор прямоугольников, и мне нужно будет вычислить до 3 ограничивающих прямоугольников, которые образуют наименьшую площадь. bounding rects

Черные прямоугольники - это набор прямоугольников, тогда как красные прямоугольники - это ограничивающие рамки (до 3), которые образуют наименьшую возможную площадь. Необходимо выработать наилучшую комбинацию ограничительных рамок.

Ответы [ 4 ]

1 голос
/ 20 февраля 2011

Как и большинство 3-х прямоугольников, все всегда будет ориентировано и выровнено по оси xy, и перекрытия нет?Вам повезло, есть O(n<sup>2</sup>) наборов из 3 таких прямоугольников, и довольно легко перечислить их с помощью O(n<sup>3</sup>) работы.Учитывая, что вы имеете дело с небольшим количеством черных прямоугольников для визуального отображения, перечисление их всех и выбор лучшего из них должны быть более чем достаточно быстрыми.

Сначала давайте подумаем о случае с 2 ограничительными прямоугольниками, потому чтоэто проще.Легко проецировать изображение на ось X, а также легко проецировать изображение на ось Y.По крайней мере, один из этих двух проекций будет иметь видимый разрыв без перекрытия.Поэтому мы можем перечислить возможные способы деления на два прямоугольника, сначала спроецировав все чёрные на отрезки линии на оси x, ищем промежутки и для каждой щели восстанавливаем, какую пару ограничивающих прямоугольников мы получили.Затем повторите процедуру с осью Y.И мы получим их все.

Теперь случай с 3 ограничительными прямоугольниками аналогичен.Оказывается, что учитывая 3 непересекающихся прямоугольника, которые ориентированы вдоль оси xy, либо проекция x, либо проекция y должна иметь видимый зазор.Таким образом, мы можем сделать ту же процедуру, что и раньше, но вместо того, чтобы просто построить пару ограничивающих прямоугольников, мы попробуем способы создать один ограничивающий прямоугольник и разделить другой на 2, используя тот же алгоритм.

(Покак вам повезло, что вы только что хотели 3. Этот подход ломается в случае ограничивающего прямоугольника 4. Поскольку тогда возможно иметь 4 ограничивающих прямоугольника, чтобы ни x-проекция, ни y-проекция не имели видимых промежутков.)

Так как же взять n черных прямоугольников, спроецировать их на одну ось (скажем, на ось x) и найти наборы ограничивающих прямоугольников?Вы просто сортируете их, строите максимальные интервалы перекрытия и находите промежутки.Вот так:

function find_right_boundaries_of_x_gaps (rectangles) {
  var ordered_rect = rectangles.sort(function (r1, r2) { return r1.x1 <=> r2.x2 });
  var gaps = [];
  var max_right = ordered_rect[0].x2;
  for (var i = 0; i < ordered_rect.length; i++) {
    if (max_right < ordered_rect[i].x1) {
      gaps.push(max_right);
    }
    if (max_right < ordered_rect[i].x2) {
      max_right = ordered_rect[i].x2;
    }
  }
  return gaps;
}

Учитывая разрыв, легко определить 2-прямоугольный ограничивающий прямоугольник для того, что лежит на каждой стороне.(Еще проще, если у вас есть упорядоченные прямоугольники, чтобы сделать это.)

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

Первый - создать замыкания, которые при вызове будут выполнять итерацию по разным структурам данных, которые вам нужны.См. http://perl.plover.com/Stream/stream.html для вдохновения.Идея здесь состоит в том, что вы пишете функцию, которая принимает набор прямоугольников и возвращает поток пар ограничивающих прямоугольников, а затем другую функцию, которая принимает набор прямоугольников, получает поток пар ограничивающих прямоугольников и возвращает поток триплетов.ограничивающих рамок.Затем имейте фильтр, который берет этот поток и находит лучший.

Другой изнутри от этого.Вместо того, чтобы возвращать функцию, которая может перебирать возможности, передавать функцию, перебирать возможности и вызывать функцию для каждой возможности.(Упомянутая функция может также выполнять дальнейшую итерацию.) Если у вас есть какие-либо воздействия на блоки в Ruby, этот подход может иметь для вас большой смысл.

Если вы не знакомы с замыканиями, вы можете пожелатьигнорировать последние несколько абзацев.

1 голос
/ 20 февраля 2011

Это довольно простой пример. Идея состоит в том, чтобы «вырастить» ваши ограничивающие рамки, очень как MST . Я чувствую, что проблема похожа на MST, за исключением того, что у нас есть до 3 непересекающихся деревьев, что значительно увеличивает сложность.

Алгоритм занимает около (n выбрать 3) * (3 * n) шагов или O (n ^ 4).

  1. Количество прямоугольников.
  2. Выберите любую комбинацию из 3 прямоугольников. Для каждой комбинации:
    1. Установите ваши три начальные ограничивающие рамки на их ширину / высоту.
    2. Для каждого оставшегося прямоугольника:
      1. Найдите область, на которую он увеличит ограничивающий прямоугольник, если он будет добавлен в этот прямоугольник для всех трех.
      2. Добавьте его в коробку с минимальным увеличением размера (измените размер этой ограничительной рамки).

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

0 голосов
/ 20 февраля 2011

Я согласен с предыдущим комментарием "mu is too short".Один алгоритм, который решает вашу проблему, может разделить все существующие «черные» прямоугольники на один-три геометрических кластера на основе умножения горизонтальной и вертикальной составляющих расстояния между каждой парой «черных» прямоугольников (это даствы область гипотетического "красного" прямоугольника, образованного между каждой парой), а затем связываете каждый получившийся кластер с "красным" прямоугольником.

Независимо от того, какой алгоритм геометрической кластеризации вы выберетеДля решения этого компонента проблемы (подробнее об этом ниже) важно, чтобы вы не разделяли «черные» прямоугольники на кластеры, используя в качестве параметра «прямое» или евклидово расстояние между каждой парой, поскольку ваша задача заключается в уменьшении площадь ограничительных ("красных") прямоугольников.Как я упоминал в предыдущем абзаце, вам нужно умножить горизонтальную и вертикальную составляющие расстояния между каждой парой "черных" прямоугольников, чтобы учесть возможную область .ограничивающий «красный» прямоугольник накрыл бы.

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

Не стесняйтесь спрашивать о любых необходимых разъяснениях и удачи в вашем проекте!

0 голосов
/ 20 февраля 2011

Не существует ли единственного наименьшего ограничивающего прямоугольника?Просто возьмите max и min x- и y-координаты среди всех прямоугольников и сделайте прямоугольник из этих спецификаций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...