在java中的矩阵中找到“匹配”的有效方法

时间:2009-06-12 22:06:59

标签: java algorithm data-structures matrix bit-manipulation

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

举例说明,假设我有访问组[V-Z]和订单[A-F]

      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”同样有效,那将是理想的

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

1 个答案:

答案 0 :(得分: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)。

特别是,如果名义矩阵是稀疏的(也就是说,如果有很多访问组,每个订单都有几个订单),这将使得裤子在一个bitset方法中击败,这将浪费大量的空间在零上,ORing上的时间归零。