从矩阵的可达性矩阵中获取前件集的最有效算法是什么

时间:2016-05-23 13:58:18

标签: java algorithm sparse-matrix

我有一个hashmap形式的可达性矩阵。键是行号,值是可达性矩阵非零的列列表。我想从这个矩阵生成先行集。它是通过读取每列的非零条目而开发的。矩阵有5000行。如果我想使用for循环来检查每个键的值集中是否存在每个键,则迭代次数为i 5000 * 5000。我想避免这种情况。是否有任何有效的算法可以避免这么多迭代。

2 个答案:

答案 0 :(得分:1)

我认为最好的方法是迭代矩阵中 的值,而不是 在矩阵中的值。由于矩阵是按行而不是按列组织的,这意味着以相同的方式导航:

final Map<Integer, List<Integer>> reverseReachabilityMatrix = new HashMap<>();
for (final Map.Entry<Integer, List<Integer>> reachabilityMatrixRow :
        reachabilityMatrix.entrySet()) {
    final Integer rowNumber = reachabilityMatrixRow.getKey();
    final List<Integer> columnNumbers = reachabilityMatrixRow.getValue();
    for (final Integer columnNumber : columnNumbers) {
         if (!reverseReachabilityMatrix.containsKey(columnNumber)) {
             reverseReachabilityMatrix.put(columnNumber, new ArrayList<>());
         }
         reverseReachabilityMatrix.get(columnNumber).add(rowNumber);
    }
}

(其中reverseReachabilityMatrix只是同一矩阵的列式表示。)

(注意:reverseReachabilityMatrix中的结果列表不会有任何有意义的顺序。如果您需要它们,那么您需要以某种方式调整上述内容。例如,您可以使用for (int rowNumber = 1; rowNumber <= numRows; ++rowNumber)而不是按内部顺序迭代HashMap。)

顺便提一下,虽然我保留了上面的HashMap<Integer, List<Integer>>结构以保持与您已经拥有的结果的一致性,但我必须说HashMap<Integer, List<Integer>>在这里似乎不是正确的数据结构,对于两个原因:

  • 如果您的行号是1到 n ,并且如果大多数行至少有一个非零条目,那么它的效率会更高(包括时间和空间) )使用数组或ArrayList结构。这不会改变渐近复杂度,但它应该在实际运行时间产生明显的差异。
  • 似乎contains在这里是一个常见的操作;您经常需要检查给定行号的可达性列表是否包含给定的列号。因此,Set,例如TreeSet似乎更合适。 (使用ArrayList时,contains方法必须遍历整个列表。)

答案 1 :(得分:0)

您是否考虑将非零元素存储在较小的矩阵中并保留每列的零元素计数?