我寻找一种算法,该算法将枚举所有非负整数K
- by - K
矩阵,使得行和列总和为给定值。
准确地说:给定K
- 非负整数m
,n
和sum(m) = sum(n)
的向量,我会搜索所有矩阵X=(x_{ij})
,以便{ {1}}和sum(x_{ij},i=1,...,K) = m_j
。
因此,每一行都是sum(x_{ij},j=1,...,K) = n_i
对应元素的整数分区,每列是n
对应元素的整数分区。
答案 0 :(得分:1)
这不是一个难题。给定矩阵条目的部分分配,存在多项式时间算法以检查是否存在至少一个满足矩阵(在指定矩阵条目的任何地方具有容量下限/上限的最大流量)。这直接导致多项式延迟枚举算法:走一棵树,其中每个内部节点对应于“将当前矩阵条目增加一个”或“移动到下一个条目”之间的决策。
答案 1 :(得分:1)
您的问题可能会成为线性代数和/或整数线性编程中的问题。有k x k
个变量和k + k
个等式。该系统可以通过标准技术减少,例如Smith Normal Form。这种方法的问题是确保所有变量都是非负的。我怀疑要找到所有解决方案,您只需要逐步通过参数空间,当出现负数时停止。我怀疑有一种更有效的方法,但这只是一种直觉。
或者您可以将问题视为整数线性规划问题,具有常量(或其他非实质)目标,如minimize 0x_{ij}
或minimize d
其中d
不是出现的变量别处。有关示例,请参阅http://www.aiexp.info/calculating-all-feasible-solutions-of-ilp.html。
无论如何,回到线性代数。由于存在k^2
个变量和2k-1
个约束(其中一个约束是多余的,因为所有"跨"等式的总和等于所有" down&#的总和34;方程式),有k^2-2k+1 = (k-1)^2
个自由变量。这应该让我们寻找一个自由变量的正方形子矩阵。实际上,我们可以将任何方形小调(例如左上角(k-1)x(k-1)
角落)视为空闲。这将确定位置(i,k)
,i<k
以及位置(k,j)
,j<k
中的值。最后,底角(k,k)
由其上方的所有条目或其左侧确定。 (这两种方法应该一致。)
使用这个想法,我看到了两种不同的方法。第一种方法是填充从所有1的方形(k-1)x(k-1)
子矩阵开始的自由变量,并增加它们的里程表样式。在每个步骤中,计算边缘和拐角变量,并在其中一个计算值达到0时停止扩充某个数字。可以置换行和/或列,以便在战略时使用最小的总和(或者或者最后,我不确定。我为k = 3手动完成了这项工作。这需要很长时间,因为有很多答案。
更智能的方法如下。不是确定(k-1)x(k-1)
子矩阵,而是确定边缘上的其他值((i,k)
和(k,j)
位置)。角落是&#34;超定的&#34;所以我们必须小心我们做事的顺序,否则它就是直截了当的。然后,它告诉我们每行和每列中剩余元素的总和应该是多少,因此我们将kxk
矩阵上的问题减少到(k-1)x(k-1)
矩阵上的问题。换句话说,我们可以使用递归。
使用k=3
问题来完成整个过程是有益的,其中所有行和列总和为4.填充右边和底边的各种方法如下:
XX1 XX1 XX1 XX2 XX2
XX1 XX2 XX2 XX1 XX1
112 121 211 121 211
在第一种情况下,我们得到了减少的问题
XX = 3
XX = 3
==
33
为了解决这个问题,我们按照上面的步骤,使用较小的矩阵。可能的边缘是
X1 X2
12 21
直接导致解决方案
21 12
12 21
将它们替换为它们来自的3x3
矩阵,我们得到以下解决原始问题的方法:
211 121
121 211
112 112
接下来考虑3x3
情况
XX1
XX2
121
这导致2x2
问题
XX=3
XX=2
==
32
在这种情况下唯一有效的边缘是
X1
11
提供了唯一的解决方案
21
11
替换回来的3x3
情况,我们得到另一个原始问题的解决方案,
211
112
121
等等。
答案 2 :(得分:1)
我从评论中看到,您正在寻找问题的名称,以便找到实施或一些文献。因此,您的问题名称是:“枚举具有固定边距的列联表”,实际上非常复杂(除了2行和2列的情况)。它被称为#P-complete,即使你只有2行和n列。因此,通常,使用近似算法来计算解(或mcmc算法以随机生成它们)。 奇怪的是,D.Knuth和F.Ruskey都将这个问题作为各自书籍的练习 This paper提供了对精确算法和近似算法的良好(不是最新)评论。 一个典型的应用是用于计算Fisher精确测试的统计数据,因此搜索它也会产生很好的结果。