c++ - 在 C++ 中确定给定 NxN 矩阵的所有方子矩阵

标签 c++ matrix code-generation submatrix

给定一个 NxN 方阵,我想通过删除相等数量的行和列来确定所有可能的方子矩阵。

为了确定所有可能的 2x2 矩阵,我需要循环 4 次。同样,对于 3x3 矩阵,我需要循环 6 次,依此类推。有没有办法在 C++ 中生成代码,以便动态生成循环代码?我已经检查了一些与 C++ 代码生成相关的答案,但其中大多数使用 python。我对python一无所知。那么,是否可以用C++编写代码生成代码呢?

最佳答案

如果我明白你在说什么,你的意思是你需要 M 次循环来选择 M 行,并为 M x M 子矩阵的 M 列选择 M 次循环,1 <= M <= N

您不需要 2*M 循环来执行此操作。无需动态生成循环次数不断增加的代码!

本质上,您需要“组合”所有可能的组合 i_{1}, i_{2}, ..., i_{M} 和 j_{1}, j_{2}, ..., j_{ M} 使得 1 <= i_{1} < i_{2} < ... < i_{M} <= N(j 也类似)

如果您拥有所有此类 i_{1}, ..., i_{M} 的所有可能组合,您基本上就完成了。

例如,假设您正在使用 10 x 10 矩阵,并且您需要 4 x 4 子矩阵。

假设您最初选择了第 {1, 2, 3, 4} 行和第 {1, 2, 3, 4} 列。接下来选择列 {1, 2, 3, 5}。接下来是 {1, 2, 3, 6} 等等,直到 {1, 2, 3, 10}。接下来选择 {1, 2, 4, 5},接下来选择 {1, 2, 4, 6} 等等,直到到达 {7, 8, 9, 10}。这是一种可以生成序列中所有(“10 选 4”)组合的方法。

继续,编写一个生成此序列的函数,您就完成了。它可以将 M、N、当前组合(作为 M 值的数组)作为输入并返回下一个组合。

您需要调用此序列来选择下一行和下一列。

我把这个放得有点松散。如果有什么不清楚,我可以编辑以更新我的答案。


编辑:

我假设循环索引从 0 开始(C++ 方式!)。为了进一步详细说明该算法,给定一个组合作为输入,可以通过将该组合视为各种“计数器”(除了没有数字重复)来生成下一个组合。

免责声明:我没有运行或测试下面的代码片段。但是这个想法在那里供您查看。另外,我不再使用 C++。容忍我的任何错误。

// Requires M <= N as input, (N as in N x N matrix)
void nextCombination( int *currentCombination, int M, int N ) {
    int *arr = currentCombination;
    for( int i = M - 1; i >= 0; i-- ) {
        if( arr[i] < N - M + i ) {
            arr[i]++;
            for( i = i + 1, i < M; i++ ) {
                arr[i] = arr[i - 1] + 1;
            }
            break;
        }
    }

}

// Write code for Initialization: arr = [0, 1, 2, 3]
nextCombination( arr, 4, 10 );
// arr = [0, 1, 2, 4]

// You can check if the last combination has been reached by checking if arr[0] == N - M + 1. Please incorporate that into the function if you wish.

编辑:

Actually I want to check singularity of all possible sub matrices. My approach is to compute all submatrices and then find their determinants. How ever after computing the determinant of 2x2 matrices , I'll store them and use while computing determinants of 3x3 matrices. And so on. Can you suggest me a better approach. I have no space and time constraints. – vineel

使用您建议的直接方法是根据构成子矩阵的行列组合对行列式进行索引。首先将 1 x 1 子矩阵的行列式存储在 HashMap 中(基本上是条目本身)。

因此对于 10 x 10 的情况, HashMap 看起来像这样
{ “0-0”:arr_{0, 0}, “0-1”:arr_{0, 1}, . . . “1-0”:arr_{1, 0}, “1-1”:arr_{1, 1}, . . . "9-9": arr_{9, 9} }

当M = 2时,你可以使用通常的公式计算行列式(1 x 1子矩阵的行列式已经初始化),然后添加到 HashMap 中。 2 x 2 子矩阵的哈希字符串类似于 1:3-2:8,其中原始 10 x 10 矩阵中的行索引为 1,3,列索引为 2, 8. 通常,对于 m x m 子矩阵,可以通过查找所有必要的(已经)计算的 (m - 1) x (m - 1) 个行列式来确定行列式 - 这是一个简单的 HashMap 查找。再次,计算后将行列式添加到 HashMap 中。

当然,您可能需要稍微修改 nextCombination() 函数 - 它目前假定行和列索引从 0 运行到 N - 1。

另一方面,由于所有子矩阵都是从 1 x 1 开始处理的,因此您不需要 nextCombination() 函数之类的东西。给定一个 2 x 2 的矩阵,你只需要再选择一行和一列来组成一个 3 x 3 的矩阵。因此,您需要选择一个行索引(它不是构成 2 x 2 子矩阵的行索引的一部分)和一个类似的列索引。但是对每个 2 x 2 矩阵执行此操作将生成重复的 3 x 3 矩阵 - 您需要考虑一些方法来消除重复项。避免重复的一种方法是仅选择索引大于子矩阵中最高行/列索引的行/列。

我再次粗略地定义了这个想法。您可以在此基础上进行构建。

关于c++ - 在 C++ 中确定给定 NxN 矩阵的所有方子矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37841369/

相关文章:

c++ - 我可以在不复制其内容的情况下删除 boost::multi_array 的单个维度吗?

c++ - 完整的模板特化不起作用 : no instance of function template "mysort2" matches the specified type STLTests

algorithm - 如何在内存方法中打印值-动态编程

code-generation - 如何为 Pharo 或 Squeak 中的类自动生成 getter/setter 代码?

java - Byte Buddy : java. lang.AbstractMethodError:调用方法时出错

c# - 代码生成工具,为单元测试创​​建 C# 适配器类?

c++ - 如何获取正确的线程 ID 和值

c++ - ifstream 和 ofstream 中的 filebuf

python - 使用 NumPy 计算特征向量的说明

haskell - 为什么 sum == foldl1 (+) 不是?