繁体   English   中英

在Java矩阵中查找“匹配项”的有效方法

[英]Efficient way to find “matches” in a matrix in java

我有一个为订单簿建模的现有(java)应用程序,因为它可以使每个订单彼此可见。 现在需要放置(有效的)每个订单的ACL。

举例说明,假设我有访问组[VZ]和订单[AF]

      A B C D E F
   V  1 0 0 1 1 0
   W  0 1 1 0 0 1
   X  0 0 0 0 1 1
   Y  1 1 0 0 0 1
   Z  0 1 0 1 0 0

出现一个新订单,将可见性指定为W&Y。什么是返回传入订单可以看到的一组值的快速方法?

建议的一种实现方式是将每一行表示为一个BitSet并执行W | | | | |。 是的,尽管我想知道随着矩阵尺寸的增加性能会发生什么变化。

一个不错但不是必不可少的功能是允许在一个维度上建立父子关系,例如

        A B C D E F
   V    1 0 0 1 1 0
   W    0 1 1 0 0 1
   X-1  0 0 0 0 1 1
   X-2  1 0 0 0 1 1
   X-3  0 1 0 0 1 1
   Y    1 1 0 0 0 1
   Z    0 1 0 1 0 0

如果将“ W | X”检索为“ W | X-1”同样有效,那将是理想的

非常感谢在算法和/或适当的数据结构方向上的任何提示。

简单的解决方案:

class AccessGroupName { ... }
class Order { ... }

Map<AccessGroupName, Collection<Order>> visibility = new HashMap<AccessGroupName, Collection<Order>>();

addVisibility(AccessGroupName group, Order order) {
    Collection<Order> orders = visibilities.get(group);
    if (orders == null) {
        orders = new ArrayList<Order>();
        visibility.put(group, orders);
    }
    if (!orders.contains(order)) orders.add(order);
}

public Set<Order> getVisibility(Collection<AccessGroupName> names) {
    Set<Order> visible = new HashSet<Order>();
    for (AccessGroupName name: names) {
        visible.addAll(visibilities.get(name));
    }
    return visible;
}

HashMap查找为O(1)。 迭代ArrayList为O(n)。 将项目添加到HashSet是O(n)。 总体而言,这将是O(n),其中n是添加列表中元素的总数(如果有重叠,则可能会超过结果集中元素的数量)。 大致来说,该常数是从ArrayList迭代器获取元素所花费的时间加上向HashSet中添加内容所花费的时间-前者约为10个周期,后者接近100个周期。

除了AccessGroupName和Order实例本身之外,内存使用情况每组大约14-15个字,每个订单大约1-2个字。 主要是对象标头。

这段代码没有做任何聪明的事情,但是我认为要以小于200个周期的常数击败O(n)会非常困难。

尤其是,如果概念矩阵稀疏(也就是说,如果有很多访问组,每个访问组有几个顺序),那么这将使比特集方法不堪一击,这将浪费大量零空间,和在一起进行或运算的时间为零。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM