我有两种树格式(exapanded树和压缩树)。它们是一种决策树,排序尝试。每个节点可以有任意数量的子节点。叶节点还包含数据。扩展树本质上是扩展的逻辑,在每个子树/节点中没有AND / OR。压缩树基本上收集扩展节点,因此人们可以更容易编辑(减少重复)。
我正在寻找一种在两棵树之间进行转换的有效方法,因为我当前的算法相当幼稚(它比O(n ^ 2)略好)。当我在扩展树中遇到约200万个节点时,它开始崩溃。
我可以搜索类似问题的关键字吗?它的分类"反转"树(一棵树中的节点中的数据成为另一棵树中的路径),尽管"反转二叉树"意味着不同的操作(更像是水平镜像的顺序)。决策树< - >表转换似乎可能相关,但数据格式略有不同?
约束:
- 扩展的树格式无法轻易更改,但如果通过更改可以获得显着的速度提升,则可以修改压缩的树格式。
- 目前有200万个扩展节点,未来几年总节点上限为1000万(实际上可能约为500万)。
- 理想情况下,限制为6GB总JVM内存,因此它可以在客户端完成,但是如果我们可以使用更多的RAM(尽管我们开始达到网络传输延迟)使其速度更快,则愿意将其移至30GB的服务器机器上
- 在完美的世界中,转换需要< 30秒。现在我约3-4分钟。
扩展和压缩树的示例:
从扩展开始时发生了什么 - >压实:
- 路径和数据基本上被反转(expandedTree数据 - > compactedTree路径和expandedTree路径 - > compactedTree数据)
**扩展节点数据用于构建压缩树中的路径(在扩展节点中的parens中)
**扩展节点中的路径进入压缩节点数据中的键/值映射(根据需要组合重复)
- 扩展节点data2和data3压缩到压缩树中的单个节点,因为它们的压缩路径相同(某些/扩展/路径),并且它们的键/值对可以一起进行OR运算(key1 == valu1 AND(key2 = = value2或value4))
- 扩展节点data2和data4无法压缩,因为它们的压缩路径不相等。
- 扩展节点data1和data2 + data3无法压缩,因为它们的路径不兼容(data1对key3 = value3有额外的约束,data2 + data3不是
)
提供有关格式的更多详细信息:
展开:
- 树下的路径是一系列键/值对。所以它基本上就像决策树或者trie。
- 只有叶数据节点对于压缩树很重要。中间路径节点可以很容易地重新生成,因为它们不包含任何数据。
- 每个数据节点都有一些值得记住的ID,因为这是主(持久)格式。
- 每个数据节点都在其中存储压缩路径,以便在转换为压缩树时知道要去哪里。这会耗费大量空间(以及转换期间的时间),因此以另一种方式执行此操作将是理想的选择。我正在考虑完全删除用户定义的分组(从扩展节点中删除此字符串),而是在压缩树转换期间压缩树上的相同节点,但不确定通过执行此操作和用户可以获得多少速度定义的分组目前对用户有用。
压实:
- 树下的路径存储在展开的树节点中,与给定节点在扩展路径中的位置无关(在完美平衡的完整树中,最左边的叶子和最右边的叶子可以具有相同的紧凑路径,因此,即使它们位于不同的扩展子树中,也会在同一个压缩节点中结束。)
- Ids在这里并不重要(事实上,如果没有人类可以捣乱它将是理想的)。但是我们是否需要记住扩展的树ID,以便以某种方式完美地重建扩展树。这是一个棘手的部分!
- 来自展开树的路径最终位于压缩节点的数据节点中的键/值映射中(请参阅示例)。这基本上将扩展节点与AND和OR组合成单个压缩节点(因此压缩)。这似乎是一个人在压缩逻辑表达式时必须解决的常见问题?
谢谢!