我有一个应用程序,想要计算通过布尔运算(内部节点)组合的基元树(叶节点)的不同表示(网格,体素化,有符号距离函数......)。
我的第一个方法是为每个不同的表示编写一个带有虚拟getter函数的抽象基类,并在各个节点上缓存中间结果,只要它们的子树没有变化(这将刷新它们的子树)高速缓冲存储器)。
然而,我对树结构与每种不同表示的丑陋耦合感到不满意。为了缓解这个问题,我删除了抽象基类,而是为每个表示设置了一个访问者。
这将树与表示整齐地分离,但让我遇到了我现在需要在其他地方缓存中间结果的问题,这就是我的问题开始的地方。
如何在树的内部节点缓存(任意多种不同类型的)中间值,而不使树依赖于值类型?
要求提供两种选择:
第一个让我感到困惑的是一些效率问题:我可以轻松地在节点中添加boost::any
(或类似的东西)的容器,但是每个访问者都必须在整个容器中搜索它['自己的数据。
第二个中的分离引入了将缓存保持为当前树的最新问题。如果树中有更改(删除,更改节点),则缓存的值必须至少无效。我的直觉是使用一些哈希函数和unordered_map
,但我也遇到了一些问题:
unordered_map
键中的值需要删除所有删除了引用的条目,或者我们在unordered_map
中有一个可能被触发的悬空引用(/指针)重新散列unordered_map
,因为密钥可能已更改我错过了一些明显的解决方案吗? 你喜欢哪种方法(以及为什么)?
答案 0 :(得分:2)
我曾遇到类似的问题,我的解决方案如下:
首先,我使用节点的地址作为ID,但出于内存原因,我不得不重复使用子树并选择路径作为ID。这样的路径具有以下优点:可以由每个访问者计算并且不需要存储在节点处。在我的例子中,每个节点最多可以有两个子节点,因此路径只是一组左/右决策,可以存储在一个简单的无符号整数中,并带有一些位移(我的树永远不会达到32的深度) ,所以一个32位无符号绰绰有余的关键)。