Я работаю над несколько сложным математическим кодом, написанным на C++. Я использую (templated) древовидные структуры для представления адаптивной функции. Из-за некоторых математических свойств я оказываюсь в ситуации, когда мне нужно перейти от одного типа узла к другому. Это должно происходить прозрачно и с минимальными издержками, как с точки зрения хранения, так и с точки зрения производительности, поскольку эти структуры используются в очень тяжелых вычислениях.Двоичное дерево с разными типами узлов
Детальная ситуация такова: у меня есть шаблонный абстрактный базовый класс, определяющий общие математические и структурные свойства общего, двусвязного узла. Каждому узлу нужна информация как от его родителя, так и от класса дерева верхнего уровня, а также для отслеживания его детей. Два класса наследуют от этого класса, FunctionNode и GenNode. Эти классы очень различаются с точки зрения хранения и функциональности, и не должны быть (по крайней мере, публичными) предками друг друга. Таким образом, я хотел бы построить дерево так:
T N /\ N N /\ G N /\ G G
где Т представляет собой дерево, Н является нормальным FunctionNode и G является GenNode. Проблема заключается в N-G-переходе: N должен иметь детей типа G, а G - родительский тип N. Так как N и G - только кузены, а не братья и сестры, я не могу преобразовать N * в G *. Достаточно, чтобы G знал, что N является BaseNode, но N должен каким-то образом хранить G полиморфно, чтобы правильные виртуальные машины вызывались автоматически при прохождении дерева. Любые идеи о том, как решить эту проблему элегантно и эффективно, будут высоко оценены! :) Конечно, можно просто взломать это, но так как это очень фундаментальный кусок кода, я бы хотел иметь хорошее решение для него. Вполне вероятно, что в будущем будет много выводов этого кода.
С наилучшими пожеланиями,
Jonas Juselius
центр теоретической и вычислительной химии, Университет Тромсё
Спасибо, это одно из решений, которые я рассмотрел. Одна из проблем заключается в том, что я не знаю заранее, будет ли следующий N N или N_g. Кроме того, иногда мне нужно обрезать все G: s и генерировать больше N: s, прежде чем, возможно, создать еще несколько G: s. –
Когда я создаю N, я понятия не имею, будет ли он листовым узлом или нет. Создано N, на нее проецируется функция с использованием квадратуры, и выполняется серия линейных преобразований, которая в конце решает, является ли N листом или нет. Я назвал дерево двоичным, но это дерево тензорного пространства, что означает, что количество операций и потребности в памяти быстро взорвались в вашем лице, поэтому я должен быть осторожным. Я очень ценю ваши материалы, и я изучаю ваши идеи :) Я могу немного поработать во время строительства, но доступ/использование должно быть смазанным жиром. –
Замена листа-N: s с помощью N_g: s - это, пожалуй, очень хорошее решение, так как в итоге у него должно быть очень мало штрафа за производительность. –