当前位置: 首页 > 知识库问答 >
问题:

枚举具有固定行和列和的矩阵组合

赫连骏
2023-03-14

我试图找到一种算法(不是matlab命令)来枚举所有可能的NxM矩阵,其约束条件是每个单元格中只有正整数(或0)以及每行和每列的固定和(这些是算法的参数)。

例:枚举所有2x3矩阵,行总计为2,1,列总计为0,1,2:

| 0 0 2 | = 2
| 0 1 0 | = 1
  0 1 2

| 0 1 1 | = 2
| 0 0 1 | = 1
  0 1 2

这是一个相当简单的例子,但是随着N和M的增加,以及总和的增加,可能会有很多可能性。

编辑1

我可能有一个有效的安排来启动算法:

matrix = new Matrix(N, M) // NxM matrix filled with 0s
FOR i FROM 0 TO matrix.rows().count()
  FOR j FROM 0 TO matrix.columns().count()
    a = target_row_sum[i] - matrix.rows[i].sum()
    b = target_column_sum[j] - matrix.columns[j].sum()
    matrix[i, j] = min(a, b)
  END FOR
END FOR

target_row_sum[i]是第一行的预期金额。

在上面的例子中,它给出了第二种安排。

编辑2:(根据j_random_hacker最后的陈述)

设M为验证给定条件的任意矩阵(行和列和固定、正或空单元格值)。设(a,b,c,d)为M中的4个单元格值,其中(a,b)和(c,d)在同一行上,(a,c)和(b,d)在同一列上。设Xa为包含a的单元格的行号,Ya为其列号。

示例:

| 1 a b |
| 1 2 3 |
| 1 c d |
-> Xa = 0, Ya = 1
-> Xb = 0, Yb = 2
-> Xc = 2, Yc = 1
-> Xd = 2, Yd = 2

这里有一个算法,可以得到所有的组合,验证初始条件,只使a,b,c和d变化:

// A matrix array containing a single element, M
// It will be filled with all possible combinations
matrices = [M]

I = min(a, d)
J = min(b, c)
FOR i FROM 1 TO I
    tmp_matrix = M
    tmp_matrix[Xa, Ya] = a - i
    tmp_matrix[Xb, Yb] = b + i
    tmp_matrix[Xc, Yc] = c - i
    tmp_matrix[Xd, Yd] = d + i
    matrices.add(tmp_matrix)
END FOR
FOR j FROM 1 TO J
    tmp_matrix = M
    tmp_matrix[Xa, Ya] = a + j
    tmp_matrix[Xb, Yb] = b - j
    tmp_matrix[Xc, Yc] = c + j
    tmp_matrix[Xd, Yd] = d - j
    matrices.add(tmp_matrix)
END FOR

然后应能找到矩阵值的所有可能组合:

  1. 对每个可能的4个单元组的第一个矩阵应用该算法
  2. 递归地将算法应用于通过上一次迭代获得的每个子矩阵,用于除已在父执行中使用的任何组之外的每个可能的4个单元组

递归深度应为(N*(N-1)/2)*(M*(M-1)/2),每次执行产生((N*(N-1)/2)*(M*(M-1)/2)-深度)*(I J 1)子矩阵。但这会产生大量重复矩阵,因此可能会对其进行优化

共有2个答案

全流觞
2023-03-14

对于NXM矩阵,有NXM未知数和nm方程。将随机数放在左上角(N-1)X(M-1)子矩阵上,除了(N-1,M-1)元素。现在,您可以轻松地找到其余N M元素的闭合形式。

更多细节:共有T=N*M个元素

有R=(N-1)(M-1)-1个随机填写的元素

剩余未知数:T-S=N*M-(N-1)*(M-1)1=N*M

刘和正
2023-03-14

你需要这个来计算费希尔的精确测试吗?因为这需要您正在做的事情,并且基于该页面,似乎通常会有大量的解决方案,所以如果您想要每个解决方案,您可能不会比暴力递归枚举做得更好。OTOH似乎蒙特卡罗近似被一些软件成功地使用,而不是成熟的枚举。

我问了一个类似的问题,这可能会有所帮助。虽然这个问题涉及的是保持每行和每列中字母的频率,而不是求和,但有些结果可以跨行翻译。例如,如果您找到任何带有数字的子矩阵(一对不一定相邻的行和一对不一定相邻的列)

xy
yx

然后你可以把这些重新排列成

yx
xy

不更改任何行或列和。然而:

  • mhum的回答证明,通常存在有效矩阵,这些矩阵不能通过任何2x2交换序列来达到。这可以通过他的3x3矩阵和映射A来看出-

更一般地说,如果你有任何子矩阵

ab
cd

如果(不一定是唯一的)最小值是d,那么可以用任何d1矩阵替换它

ef
gh

其中h=d-i,g=c i,f=b i和e=a-i,对于任意整数0

 类似资料:
  • 给定矩阵(大小by)和幂,(例如,4),产生矩阵,其中每个-th矩阵包含所有中的列在该程度上的可能组合。 在我当前的方法中,我生成-th矩阵,然后在下一次调用中使用它来生成th矩阵。对于给定的功率,这是否可以“自动”完成,而不是手动完成? 说到R,我是一个新手,我明白有可能比下面的尝试更有效、更优雅地实现这个解决方案。。。 有人能提供一些建议吗?我的目标是为给定的矩阵创建一个函数,并以更“自动化”

  • 基于我下面链接的相关问题(请参见@Aleh solution):我希望只计算给定幂的矩阵中列之间的唯一乘积。 例如,对于N=5,M=3,p=2,我们得到列(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)的乘积。我想修改(@Aleh)代码,只计算(1,1)、(1,2)、(1,3)、(2,2)、(2,3)、(3,3)列之间的乘积。但我想对每个第

  • 给定一个大小为N的非负整数的未排序数组,找到一个与给定数S相加的连续子数组。 输入: 输入的第一行包含一个整数T,表示测试用例的数量。接下来是T测试用例。每个测试用例由两行组成。每个测试用例的第一行是N和S,其中N是数组的大小,S是和。每个测试用例的第二行包含N个表示数组元素的空格分隔整数。 输出: 对于每个测试用例,在新行中,如果sum等于子数组,则从左侧打印第一个出现子数组的开始和结束位置(1

  • 枚举类(“新的枚举”/“强类型的枚举”)主要用来解决传统的C++枚举的三个问题: 传统C++枚举会被隐式转换为int,这在那些不应被转换为int的情况下可能导致错误 传统C++枚举的每一枚举值在其作用域范围内都是可见的,容易导致名称冲突(同名冲突) 不可以指定枚举的底层数据类型,这可能会导致代码不容易理解、兼容性问题以及不可以进行前向声明 枚举类(enum)(“强类型枚举”)是强类型的,并且具有类

  • 我有一个.Net Core v2.1 Web API,它使用NSwag生成其Swagger Json。 我有一个这样的反应模型- 生成Swagger JSON的- 当在JSON上运行swagger代码时,我在我的IO. Swagger项目中获得了以下LoginResault模型,用于C#(选择了目标框架5.0)- 有人可以帮助描述我如何让枚举生成与IO. Swagger中的原始LoginResul

  • 问题内容: 我需要在网页上显示一个大表,并且需要防止第一列和第一行滚动。 我想动态设置此表的垂直大小(在某些静态大小的页眉/页脚页面内容之间),以使其尽可能高,而不必强制浏览器窗口具有垂直滚动条。 这仅需要在使用所有/任何版本的现代浏览器中工作:html,css,javascript,jquery 重要顺序: 具有许多表单字段,隐藏值,行的javascript折叠等的复杂表,稍后将添加 第一行将有