2012-06-22 2 views
0

У меня есть контейнер геометрических объектов. Предположим, что есть круг, эллипс, линия, дуга. Для каждого объекта я могу получить конечную точку конечной точки и сущность объекта.Слияния/соединения геометрических объектов

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

Итак, мы имеем: сущность, начальные конечную точку, ID

Я хочу, чтобы назначить для каждого подключенного объекта одинакового идентификатора.

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

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

Надеюсь, что проблема хорошо определена, а метки - в порядке. Если нет, прокомментируйте или отредактируйте. Я постараюсь предоставить более подробную информацию.

+0

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

+0

Две петли, которые вы имеете в виду Loop {Loop}, поэтому вторая петля вложена в первую очередь? – krzych

+0

Да. Позвольте мне сделать правильный ответ с псевдокодом. –

ответ

1

В дополнение к предложению @ RafaelBaptista о хэш-точке конечной точки для эффективного общего решения требуется disjoint-set datastructure, что решает проблему назначения одного идентификатора для связанных групп объектов.

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

+0

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

+0

Возможно, мне стоит рассмотреть какой-то самый длинный путь поиска в графе подключенных компонентов? – krzych

+0

Если вы действительно хотите самый длинный путь, тогда да: обрабатывайте каждый компонент как дугу, каждую конечную точку как узел и используйте соответствующий алгоритм графа. Обратите внимание, что «самый длинный путь» является NP-полным, но для небольших графиков вы должны быть в порядке. – comingstorm

1

Для небольшого числа лиц:

for (u32 i = 0; i < numEntities; i++) 
{ 
    for (u32 j = i+1; j < numEntities; j++) 
    { 
     if (hasCommonEndpoint(entity[i], entity[j])) 
      setSameId(entity[i], entity[j]) 
    } 
} 

Это масштабируется, как O (N^2), так что он взорвется, если у вас есть большое количество лиц. Он также предполагает, что объекты, которые соответствуют конечной точке, не будут совпадать ни на одной другой конечной точке. Если это произошло, вам нужно разрешить сущностям иметь более одного идентификатора.

Обратите внимание, что внутренний цикл начинается для j> i, поэтому вы не сравниваете один и тот же объект более одного раза. Это сократит время пополам.

Если у вас есть большое число количество объектов вы хотите сделать что-то вроде:

HashTable<endpointHash, entity> dict; 
for (u32 i = 0; i < numEntities; i++) 
{ 
    dict.insert(entity[i].endpointHash(), entity[i]); 
} 

Где HashTable хостов список всех лиц, которые имеют конечные точки с одной и той же конечной хэш. Затем для каждого списка перебирайте элементы списка, соответствующие конечным точкам, таким же образом, как и первый цикл. Это будет намного лучше примерно O (n) + O (m^2), где N велико, а M мало. Фактическая производительность будет зависеть от качества хеш-функции и количества хэш-бункеров.

+0

Спасибо за решение в псевдокоде. Конечно, это очевидно. Но оба решения не справляются с тем, что три конечных точки одинаковы. Как я уже сказал, в этом случае тот же идентификатор должен быть назначен для объектов, которые создают самую длинную цепочку. Поэтому для подключения следует выбрать объект, к которому может быть подключено большее количество объектов. – krzych

+0

Нет. Это будет работать, если есть несколько объектов с одинаковыми конечными точками.Что не будет работать, если у вас есть сущность A с одной общей точкой с B, а другая с C, но C и B не имеют общего. –

+0

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

Смежные вопросы