Маркировка подключенных компонентов по случайно разделенным данным?

В настоящее время мне поручено реализовать алгоритм CCL в системе баз данных (написанной на C++). Этот алгоритм будет назначать метку всем значениям заданного многомерного массива, которые превышают пороговое значение, а соседние помеченные значения будут иметь одну и ту же метку.

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

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

-=-=-=-

В настоящее время у меня это работает, делая следующее:

  1. Каждый экземпляр создает массив логических значений размера, равного количеству элементов в массиве, и устанавливает для всех значений значение FALSE.

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

  3. Все экземпляры отправляют свои массивы координатору, который объединяет результаты с помощью оператора ИЛИ для создания окончательного логического вектора.

  4. Координатор просматривает каждое значение в массиве, пропуская уже помеченные значения. Если значение не помечено и логическое значение, соответствующее этому значению, равно true, оно присваивает ему новую метку и рекурсивно присваивает всем своим соседям (и соседям соседей и т. д.) одну и ту же метку.

  5. Возвращается вектор меток.

Алгоритм, описанный выше, работает, но единственное преимущество наличия нескольких экземпляров — это расчеты пороговых значений. Поскольку эта реализация просто собирает все и сканирует на координаторе, она, скорее, лишает смысла использование нескольких экземпляров.

-=-=-=-

По сути, этот алгоритм автоматически превращается в алгоритм «разделяй и властвуй», но деление происходит полностью и неконтролируемо случайно.

Мы хотим воспользоваться этим разделением, выполнив обе проверки CCL на каждом экземпляре, а затем объединив эти локальные результаты CCL на координаторе; то есть, если два экземпляра создают группы меток, которые соседствуют друг с другом, мы хотим объединить эти две метки без повторного сканирования каждого значения. Этот пункт, выделенный курсивом, доставляет нам больше всего проблем, и мы довольно потеряны относительно того, как продолжить. Если у кого-то есть предложения по алгоритмам или структурам данных, которые было бы полезно изучить, это было бы очень признательно.


person Ingulit    schedule 11.10.2013    source источник


Ответы (1)


Компоненты, связанные с соседями (в отличие от компонентов, связанных с графом), требуют изучения набора всех пар соседних (смежных пикселей).

То есть,

  • Define the set over pairs of points that are adjacent:
    • { ((x1, y1), (x2, y2)) } for which
      • For 4-connectivity: (abs(x2 - x1) + abs(y2 - y1)) <= 1 and (x1 != x2 && y1 != y2)
      • Для 8-связности: max(abs(x2 - x1), abs(y2 - y1)) <= 1 и (x1 != x2 && y1 != y2)

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

  • рефлексивность
  • Симметрия
  • транзитивность

Из этих трех требований вытекает интересное следствие:

  • Предположим, вам дан частичный список отношений эквивалентности, например (a, b), (b, c), (c, d), (e, f)
  • Обратите внимание, что перестановка этого списка, вставка «эквивалентных» отношений эквивалентности (таких как (a, c) при условии, что (a, b) и (b, c) уже существуют) и т. д. не влияют на разбиение.

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


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

Следует изучить фактическую реализацию Disjoint-Set, а также узнать, как он фактически используется (вызывается) из алгоритма связанных компонентов.

После этого следует поднять уровень абстракции понимания - абстрактное понятие (интерфейс алгоритма) Непересекающегося-множества. Изучив эту абстракцию, вы сможете повторно реализовать Disjoint-Set необычными способами.

  • На этапе построения из основного цикла необходимо вызывать только функцию Union.
  • Функция Find используется только внутри функции Union.
  • Таким образом, можно абстрагироваться от операций Disjoint-Set, предоставив приемник для потока Union( (x1, y1), (x2, y2) ) вызовов сообщений.
  • Эти вызовы сообщений могут быть асинхронными, поставленными в очередь, произвольно переставленными, пакетными, однако вы хотели бы их обрабатывать, если все такие вызовы в конечном итоге обрабатываются полностью.
  • Это приведет к избыточным вызовам Union, потому что не будет проверяться, имеют ли два узла уже одну и ту же метку перед постановкой вызова в очередь. Этот вопрос будет рассмотрен в следующей части.

Теперь мы представим способ планирования этих Union сообщений для обработки.

Предположим, узлы распределены по разным машинам.

  • We will partition the set of pairs of adjacent pixels { ((x1, y1), (x2, y2)) } as follows:
    • For each machine, we would like to find the subset of pairs of adjacent pixels that reside on the same machine.
    • После этого нам нужно подмножество всего остального — пары смежных пикселей, находящихся на двух отдельных машинах.

Чтобы обработать Union-Find на другой машине, нужно просто * Генерировать Union сообщений из набора пар смежных пикселей на той же машине * Затем отфильтровать Union сообщений, чтобы удалить лишние. * Генерирует Union сообщений из набора пар смежных пикселей разных машин. * Выполнять сообщения на разных машинах поверх результатов сообщений на одной и той же машине.


Этот ответ написан слишком абстрактно, потому что более конкретный ответ потребует более подробной информации о проблеме, особенно в части о «полностью и неконтролируемом случайном разбиении».

person rwong    schedule 17.08.2014