更改多维树

时间:2015-10-08 07:40:05

标签: java algorithm tree

|-- Car                                |-- Green     
|   |-- Audi                           |   |-- Car        
|   |   |-- Green                      |   |   `-- Audi           
|   |   |-- Blue                       |   `-- Bike             
|   |   `-- Red                        |       `-- BMW  
|   `-- BMW                            |-- Blue     
|       |-- Red                        |   `-- Car         
|       `-- Yellow     ==========>     |       `-- Audi     ==========>     etc.                 
`-- Bike                               |-- Red         
    |-- BMW                            |   |-- Car    
    |   |-- Yellow                     |   |   |-- Audi 
    |   |-- Blue                       |   |   `-- BMW
    |   `-- Green                      |   `-- Bike       
    `-- Honda                          |       `-- Honda       
        |-- Red                        `-- Yellow          
        `-- Yellow                         |-- Car         
                                           |   `-- BMW
                                           `-- Bike
                                               |-- BMW
                                               `-- Honda

我想在树构建器中以通用方式实现几个“透视图”。

这棵树有6种可能的排列,我刚刚绘制了2种。

我尝试了什么:

  • 我正在使用通用树结构,其中每个节点都知道其父节点和子节点,并且有一个有效负载。
  • 类:TreeBuilderAbstractNodeVehicleNodeColorNodeMakerNode以及定义级别顺序的其他有序枚举列表:{ {1}},BY_VEHICLEBY_COLOR - 您可以切换这些内容以获得所需的视角
  • 遍历枚举列表,将特定于该枚举值的所有实体(汽车,制造商,颜色)收集为对象左右。使用工厂方法,使用BY_MAKER创建节点,同时传递树构建器,enumValue(对于顶级,父枚举值为NULL)。
  • Child有parentEnumValue根据getParentMember_Internal获取corect父级(使用包含所有数据映射的parentEnumValue
  • 在我提到的上一次迭代中,使用结果节点的父对象,我们可以搜索树并查看它是哪个节点(请记住,自上而下创建了级别,因此父级已经存在)

为什么不起作用:

  • 在搜索正确的父级时,树中可能有多个实例,因此我们也被迫查看祖父母。
  • 此外,分支可能会重复(参见第二棵树)

我在问什么:

  • 这种树/算法是否有特定的命名?我想不出在Google中使用的英文术语。
  • 是否与“K-D树”有关?
  • 有没有通用的方法来做这类事情?

编辑1 @Andreas

树中只有3个可能的实体:treeBuilderVehicleColor。没有“车型”。树中的所有有效负载都是这三个中的子类。

我将它们称为“有效负载”,因为每个对象都包含在Maker子类(它是树结构的一部分)中,以将数据与表示层分开。示例:AbstractNode

由于实体彼此独立,因此可能隐藏级别。 这将是一个有效的案例:

VehicleNode has a Vehicle payload

1 个答案:

答案 0 :(得分:2)

在SQL中,这类似于Star Schema,在Online Analytical Processing (OLAP)的数据仓库数据库中使用。

在您的情况下,这将是一个事实表Vehicle和3个维度(TypeBrandColor)。

我建议将车辆保留在列表中,并从列表中构建6个树/索引,而不是尝试将一棵树转换为另一棵树。

完全类型的实现可能是定义通用抽象树:

public abstract class Tree<F, D1, D2, D3> {
    protected Tree(List<F> facts) {
        // code here using getDimensionN() to build tree
    }
    protected abstract D1 getDimension1(F fact);
    protected abstract D2 getDimension2(F fact);
    protected abstract D3 getDimension3(F fact);
    public List<F> get(D1 dimension1) {
        // code here
    }
    public List<F> get(D1 dimension1, D2 dimension2) {
        // code here
    }
    public List<F> get(D1 dimension1, D2 dimension2, D3 dimension3) {
        // code here
    }
    // other public accessor methods here
}

然后,您可以使用以下代码构建特定树:

List<F> facts = ...;
Tree<Vehicle, Type, Brand, Color> typeBrandColorTree = new Tree<Vehicle, Type, Brand, Color>(facts) {
    protected Type getDimension1(Vehicle vehicle) { return vehicle.getType(); }
    protected Brand getDimension2(Vehicle vehicle) { return vehicle.getBrand(); }
    protected Color getDimension3(Vehicle vehicle) { return vehicle.getColor(); }
};

// Use of tree
List<Vehicle> audiCars = typeBrandColorTree.get(Type.CAR, Brand.AUDI);

<强>更新

Star Schema可能不适合您的特定问题,因此更多有关Star Schema的信息。让我用一个例子来说明事实可能是什么。

事实可能是销售车辆,其中跟踪的销售统计数据包括:

  • 类型(汽车,自行车)
  • 品牌(奥迪,宝马,本田)
  • 颜色(绿色,蓝色,红色,黄色)
  • 日期
  • 价格

然后可以使用树/索引来回答以下问题:

  • 显示奥迪汽车的销售情况。
  • 出售了多少辆蓝色自行车?
  • 按品牌列出总销售额。

为了更快地访问,树节点甚至可以预先聚合的值,如CountTotalPrice,这样您就不需要迭代所有事实来获得答案。

这主要用于巨大的数据集(例如10年的全国销售数据),以帮助管理人员快速按需获得各种汇总统计数据。因此,术语“在线分析处理”。