Nano Hash - криптовалюты, майнинг, программирование

Древовидная структура сериализации с использованием boost::serialization

Мне нужно сериализовать libkdtree++ в своей программе, древовидные структуры кратко описаны следующим образом:

struct _Node_base {
  _Node_base * _M_parent, *_M_left, * _M_right;

  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar & _M_left & _M_right;
  }
}

template<typename V>
struct _Node : public _Node_base {
  typedef V value_type;
  value_type value;
  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar.register_type(static_cast<_Node*>(NULL));
    ar & boost::serialization::base_object<_Node_base>(*this);
    ar & value;
  }
}

struct Tree {
  _Node * root;
  template<Archive>
  serialize(Archive &ar, const unsigned int version) {
    ar & root;
  }
}

Эта программа сообщает об "ошибке потока". Но из «файла serailzed» отсутствуют поля значений для дочерних узлов корней. Таким образом, я думаю, возможно, что BaseNode сериализовал указатели _M_left и _M_right. Однако, поскольку _Node_base не имеет понятия о типе значения _Node, поэтому сложно добавить «ar.register_type» в _Node_base.serialize().


  • Этот код не компилируется. Node должен быть подклассом BaseNode, left и right должен быть ptrs, value_type необъявленным, serialize отсутствующим типом возвращаемого значения и т. д. и т. д. Пожалуйста, опубликуйте реальный код (который компилируется). 23.07.2010

Ответы:


1

Исключение pointer_conflict документация гласит (sic):

    pointer_conflict,   // an attempt has been made to directly
                        // serialization::detail an object
                        // after having already serialzed the same
                        // object through a pointer.  Were this permited,
                        // it the archive load would result in the
                        // creation of an extra copy of the obect.

Я думаю, что конфликт возникает, когда каждый из них сериализуется с помощью ptr в BaseNode::serialize и через прямой объект, выражение *Node, в Node::serialize. Однако, поскольку функция base_object принимает ссылку, а не указатель, я не знаю, как этого избежать.

Одна из возможностей — не сериализовать указатель parent. Вместо этого после десериализации пройдитесь по дереву и исправьте родительские указатели так, чтобы они указывали на родительский узел. Например. добавьте в BaseNode следующий метод:

void fix (BaseNode* parent = 0)
{
    this->parent = parent;
    if (left != 0)
        left->fix (this);
    if (right != 0)
        right->fix (this);
}

Тогда просто позвоните root->fix ()

23.07.2010
  • У него все еще есть ошибка потока, возникающая в процессе декодирования... Я так понимаю 25.07.2010
  • класс друзей boost::serialization::access; template‹class Archive› void serialize(Archive & ar, const unsigned int version) { // сериализуем информацию о базовом классе ar.register_type(static_cast‹_Node*›(NULL)); ar & boost::serialization::base_object‹_Node_base›(*this); ар & _M_значение; } Я добавил эту функцию в libkdtree::_Node, однако я думаю, что проблема здесь в том, что функция serialize() в base_object не будет правильно сериализовать точки _left, _right, которые просто обрабатывают их как указатель _Node_base * 31.07.2010

  • 2

    Следующее решение для libkdtree++ и boost::serialization работает:

    // KDTree::_Node
    friend class boost::serialization::access;
    template<class Archive>
    //void serialize(Archive & ar, const unsigned int version)
    void save(Archive & ar, const unsigned int version) const
    {
      ar.register_type(static_cast< _Link_type>(NULL));
      ar & boost::serialization::base_object<_Node_base>(*this);
      _Link_type left = static_cast<_Link_type>(_M_left);
      _Link_type right = static_cast<_Link_type>(_M_right);
      ar & left & right;
      ar & _M_value;
    }
    
    
    template<class Archive>
    void load(Archive & ar, const unsigned int version)
    {
        ar.register_type(static_cast< _Link_type>(NULL));
        ar & boost::serialization::base_object<_Node_base>(*this);
        _Link_type left, right;
        ar & left & right;
        ar & _M_value;
        if (left) {
           left->_M_parent = this;
        } 
        if (right) {
           right->_M_parent = this;
        }
        _M_left = left;
        _M_right = right;
    }
    
    BOOST_SERIALIZATION_SPLIT_MEMBER()
    
    05.08.2010
    Новые материалы

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

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..