NVCtree中如何划分subtree

       当一棵nvc tree不断的加入名字,tree就会变得越来越大。比如我们要建一棵在一个国家下面直接找一条道路这个功能的tree。这时候的做法,就把这个tree切分成多个subtree,每个subtree可以控制在我们可以接受的大小范围内。这就引出来一个问题,如果切分出subtree?

      什么样的subtree是好的切分方法,由平均主义我们可以认为,各个subtree的大小应该一致,尽量差不多,不要一个有1m,另一个大小只有10k。


     自己尝试了2中subtree的切分方法,基本上效果还好,但是很多情况下,各个subtree的size之间还是差异比较大,特别是有些节点下面挂了很多分支,每个分支都很小,但是 当前节点作为subtree又很大,特别是中文的情况下,在道路nvc中,一个汉字下面可能接3000多个汉字。

      方法一,设定4000个节点为标准,从tree中找出一个节点,这个节点下面的子孙节点个数为大于4000中最小的一个。具体做法:

                     1,通过递归,把tree中每个节点记录下本节点包含的子孙节点的个数。

                     2,遍历一遍tree中的节点,把1中记录的个数中,大于等于4000,同时是最小的节点找到。

                     3,把这个节点当成subtree的root,把其中tree中切分出来。

                     4,重复1开始下一次查找,直到找到的节点就是tree本身的root节点。

      这个方法总是越到后面,找到的subtree大小越不一致。改进成方法二

     方法二,把大于4000中最小的节点,改成与4000的差值最小的节点。

                     1,通过递归,把tree中每个节点记录下本节点包含的子孙节点的个数。

                     2,遍历一遍tree中的节点,把1中记录的个数,计算与4000的差值,差值最小的节点找到。

                     3,把这个节点当成subtree的root,把其中tree中切分出来。

                     4,重复1开始下一次查找,直到找到的节点就是tree本身的root节点。

       改进后,找到的subtree平均很多了,不过还是有比较大的差异。这是目前本人使用的方法。


分析了上面2个方法,实现都很简单,使用了贪心算法,即每次都找到当前状态下最好的那个subtree。个人觉得,如果真要找到最优解,可能需要用到回溯策略。

不晓得有没有其他实现简单的方法。

新的思考:

       上面的方法在划分subtree的时候,共同父的子节点总是分在同一个subtree中,这导致了subtree的划分不可能达到非常平均负载。特别是中文情况,汉字的下一个汉字几百上千种情况完全可能。为了更平均的负载,应该允许共同父的子节点可以分配在不同的subtree,这样可以按需要,当部分子节点刚好填满subtree的容量,划分停止,启动一个新的subtree来包含剩下的子节点。

       同父的子节点划到一颗subtree上,好处是在当前的subtree上就可以做到完备的逻辑判断。如果把子节点分配到了2个不同subtree,这样我们需要同时对2个subtree进行逻辑判断,然后对结果进行合并去重,这样必然带来了代码的复杂性。同时,代码在解析nvctree的时候,应该能够透明处理这2种不同的划分方法,这个就需要好好设计下subtree的解析代码。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值