Моя цель состоит в том, чтобы представить трехмерное пространство, которое дискретно разделено на неоднородные ячейки.
Контейнер содержит элементы произвольного типа (тип определяется).
При добавлении ячейки (или интервала, в котором находится ячейка), и она пересекается с предыдущей добавленной ячейкой, оба должны быть объединены.
Прямо сейчас я только добавляю элементы (интервалы), и после этого я выполняю итерации, чтобы получить элементы, принадлежащие правильному элементу, но, возможно, в будущем мне может понадобиться изменить элементы / интервалы и получить доступ к элементам одновременно.
Алгоритм, который использует эту структуру данных, должен быть эффективным по времени.
До сих пор я стараюсь использовать существующие библиотеки и структуры данных, когда это возможно.
Boost :: ICL швы удобны, но проблема может быть в слиянии.
Прямо сейчас я делаю это с оберткой. F.E. только с двумя измерениями (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. Но я не самый продвинутый программист.
Итак, мои вопросы:
Несмотря на уродство моего подхода … это сработает или могут возникнуть определенные проблемы?
Существуют ли структуры данных, которые могут быть более подходящими?
Что я должен учитывать при реализации моей собственной структуры данных?
Большое спасибо за вашу помощь
Существуют ли структуры данных, которые могут быть более подходящими?
Возможно, вы ищете Boost геометрии Контейнеры пространственного индекса (например, дерево)
Возможно, это означает, что вы должны выполнить слияние, но, по крайней мере, вы получаете требования к масштабируемости бесплатно: поиск выполняется быстро, доступны пространственные запросы и итерация — это особенность.