Структура данных на основе интервалов (аналогично boost icl)

Моя цель — представить трехмерное пространство, которое дискретно неоднородно разбито на ячейки.

Бин содержит элементы произвольного типа (тип определяется).
При добавлении бина (или интервала, в котором лежит бин) он пересекается с предыдущим добавленным бином, оба должны быть объединены.

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

До сих пор я стараюсь использовать существующие библиотеки и структуры данных, когда это возможно.
Boost::ICL кажется удобным, но проблема может заключаться в слиянии.

Сейчас я делаю это с оберткой. Ф.э. только с двумя измерениями (Y, Z) и набором в виде корзины:

class Set_wrapper : public boost::enable_shared_from_this<Set_wrapper>
{
public:
    Set_wrapper() :
        mValue(new boost::shared_ptr<std::set<int> >(new std::set<int>()))
    {
    }
    Set_wrapper(const std::set<int> & s)
    {
        mValue.reset(new boost::shared_ptr<std::set<int> >(new std::set<int>(s)));
    }
    void operator+=(const Set_wrapper &s)
    {
        Set_wrapper* sp = (Set_wrapper*) &s;
        (*sp->mValue)->insert((*mValue)->begin(), (*mValue)->end());
        *mValue = *(sp->mValue);
    }
    bool operator==(const Set_wrapper &s) const
    {
        return *s.mValue == *mValue;
    }

    boost::shared_ptr<boost::shared_ptr<std::set<int>>> mValue;

};

typedef interval_map<double, Set_wrapper> ZMap;

class Z_map_wrapper : public boost::enable_shared_from_this<Z_map_wrapper>
{
public:
    Z_map_wrapper() :
        mValue(new boost::shared_ptr<ZMap>(new ZMap()))
    {
    }
    Z_map_wrapper(const ZMap & s)
    {
        mValue.reset(new boost::shared_ptr<ZMap>(new ZMap(s)));
    }

    void operator+=(const Z_map_wrapper &s)
    {
        Z_map_wrapper* sp = (Z_map_wrapper*) &s;
        for(auto it = (*mValue)->begin(); it != (*mValue)->end(); ++it)
        {
          *(*sp->mValue) += std::make_pair(it->first, it->second);
        }
        *mValue = *(sp->mValue);
    }
    bool operator==(const Z_map_wrapper &s) const
    {
        return *s.mValue == *mValue;
    }

    boost::shared_ptr<boost::shared_ptr<ZMap>> mValue;

};

typedef interval_map<double, Z_map_wrapper> YMap;

Мне это кажется немного хакерским :-)

Другим вариантом было бы написать мою собственную структуру данных, используя b-деревья или интервальные деревья (например, из cgal). Или адаптировать или расширить boost::icl. Но я не самый продвинутый программист.

Итак, мои вопросы:

Несмотря на уродство моего подхода ... это сработает или могут возникнуть определенные проблемы?

Существуют ли какие-либо структуры данных, которые могут быть более подходящими?

Что я должен учитывать при реализации собственной структуры данных?

Большое спасибо за вашу помощь


person Michael Latz    schedule 14.04.2015    source источник


Ответы (1)


Существуют ли какие-либо структуры данных, которые могут быть более подходящими?

Возможно, вы ищете Boost-геометрию Пространственный индекс контейнеры (например, rtree)

Возможно, это означает, что вам придется выполнять слияние, но, по крайней мере, вы получаете требования к масштабируемости бесплатно: поиск выполняется быстро, пространственные запросы доступны, а итерация — это функция.

person sehe    schedule 14.04.2015