java - 从矩阵的可达性矩阵中获取先行词集的最有效算法是什么

标签 java algorithm sparse-matrix

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

最佳答案

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

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 ,似乎更合适。 (对于 ArrayListcontains 方法必须迭代整个列表。)

关于java - 从矩阵的可达性矩阵中获取先行词集的最有效算法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37393034/

相关文章:

C中结构体中使用的尖点稀疏矩阵

java - 生成非常大的 Java 代码

java - 从 Java 中的 Cypher 查询检索结果缓慢 - Neo4j 2.0

javascript - 为什么我的算法显示 [循环]? (NodeJS简单算法)

arrays - 数组动态时的最小查询范围

python - 求解多个线性稀疏矩阵方程 : "numpy.linalg.solve" vs. "scipy.sparse.linalg.spsolve"

java - Android 在 API 16 中对 ArrayList<class> 进行排序?

java - 尝试添加 react 时遇到 onGuildMessageReceived() 问题

algorithm - O(n² log(n)) 算法找到数组中的所有数字,使得 x² + y² = z² + u²

python - 有效地将 Numpy/Scipy 稀疏和密集矩阵相乘