【发布时间】:2011-08-21 22:28:52
【问题描述】:
我在尝试解决一个比我想象的更难解决的问题时遇到了麻烦。给定一个 NxM 的二进制矩阵,我想在每列只有一个“1”的约束下生成所有可能的解决方案。对于 2x3,这将是:
1 1
0 0
0 0
1 0
0 1
0 0
1 0
0 0
0 1
0 1
1 0
0 0
0 0
1 1
0 0
0 0
1 0
0 1
0 1
0 0
1 0
0 0
0 1
1 0
0 0
0 0
1 1
在头疼之后,我在 C 语言中使用了一个递归算法,但我不太确定它是否正确,因为它显然在很长一段时间内都没有工作,缺少一些组合。更改递归后,至少组合的数量是正确的,对于 N x M,我可以手动检查它似乎是正确的。
但是:我一开始的内存消耗太可怕了
1 1
0 0
0 0
和最右边的列,将1设置为0,将下一行中的0设置为1,如果有任何行。然后我向左移动一列(将我所做的重置到最右边的列,比如考虑进位)并迭代 1 的位置,并且对于每次迭代,我再次向右递归,直到没有列可以迭代它的 1. 这种方法对你来说可能看起来很尴尬(代码对我来说),但我认为它就像在 polyad 系统中计数,其中列是数字,1 的位置给出了数字的值。
也许这只是我递归的坏方法,但目前我必须为每个递归复制当前数组,这当然很糟糕,但我发现的唯一方法是,例如
0 1
1 0
0 0
复制两次生成
0 0
1 1
0 0
和
0 0
1 0
0 1
彼此独立更容易。但是在递归的同时释放 C 中的内存似乎不符合我的经验水平。我已经用 Java 进行了重写,希望 GC 可以帮助我(不敢相信,但它看起来确实如此)但是再次,分析表明,复制数据当然会占用 99% 的周期。
您对我的问题有什么建议吗?甚至可能有一个名字,而不是考虑现有的算法?你手头有递归的伪代码吗?非常感谢吸烟的大脑!
我什至不确定这是组合问题还是置换问题。
【问题讨论】:
-
也许我误解了你的问题,但是处理 1 所在的行而不是传递整个矩阵,然后基于此打印输出不是更容易吗?跨度>
-
另外,我的直觉告诉我递归不是要走的路——子问题完全不依赖于以前的结果,反之亦然,问题是基本迭代,正如你正确地观察到的那样,它相当于在一个包含 N 位数字的 M 进制数系统中计数:这就是迭代!
-
添加了标签 [sparse-matrix],因为这就是该进程正在创建的内容。
-
好的,我已经解决了这个问题,但使用的是稀疏矩阵,但方式完全不同。但是我通过计算二进制来创建它们,我知道有多少组合,从零数组开始,我在循环中添加 1。进位处理很容易在一个while循环中完成,瞧。
标签: matrix permutation combinations combinatorics sparse-matrix