【发布时间】:2016-01-16 19:03:38
【问题描述】:
背景:
这是逻辑和算法课的额外功劳,我们目前正在涵盖命题逻辑,P 暗示 Q 之类的东西,所以我认为教授想给我们和分配超出我们的深度。
我将在 C++ 中实现这一点,但现在我只想了解示例中发生了什么......我不知道。
示例
附上计算数字的 Lefty 算法的演练 nxn 0-1 个矩阵,每行和每列有 t 个矩阵,但主矩阵上没有 对角线。 用于验证给出的方程的算法计算了所有可能的 矩阵,但不构造它们。 它被称为“左撇子”,相当简单,最好用 例子。 假设我们想用 2 个矩阵计算 6x6 0-1 矩阵的数量 在每一行和每一列中,但在主对角线上没有。我们首先创建一个 长度为6的状态向量,用2s填充:
(2 2 2 2 2 2)
这个状态向量表示我们必须在每个状态向量中放置的数量 柱子。我们将它与一个我们称为“冰球”的整数相伴,它是 初始化为 1。每执行一次,这个 puck 就会增加一个 放置在矩阵的一行(“圆形”)中,我们将冰球视为 “覆盖”我们将无法在该轮中放置的列。 由于我们从第一行开始(因此是第一轮),我们将 任何列中有两个,但由于 puck 是 1,我们不能将一个放在 第一列。这对应于我们必须放在第一个的强制零 列,因为 1,1 条目是矩阵主对角线的一部分。 该算法将遍历所有可能的选择,但要显示每一轮, 我们将做出选择,比如第 2 列和第 6 列。然后我们删除状态 向量通过从第 2 和第 6 值中减去 1,然后推进冰球:
(2 1 2 2 2 1); 2
对于第二轮,冰球是 2,因此我们不能在该列中放置 1。 我们选择将它们放在第 4 列和第 6 列中,并推进 冰球:
(2 1 2 1 2 0); 3
现在,我们可以在除第 3 和第 6 之外的任何地方放置两个 列。在这个阶段,算法对可能性进行不同的处理:我们 可以在冰球之前放置一些(在列索引中小于冰球 值),和/或冰球之后的一些(在列索引中大于 冰球价值)。在冰球之前,我们可以在有 1 的地方放置一个,或者 有 2 的地方;在冰球之后,我们可以在第 4 或第 5 列放置一个。 假设我们将它们放在第 4 列和第 5 列。我们删除状态向量 并再次推进冰球:
(2 1 2 0 1 0); 4
1 对于第 4 轮,我们再次注意到我们可以在 冰球,和/或之后的一些。 在冰球之前,我们可以放置:
(a) 值 2 列中的两个(1 个选项)
(b) 值2列中的一个(2个选项)
(c) 值1列中的一个(1个选择)
(d) 在值为 2 的列中一个一个,在一个值为 1 的列中一个(2 选择)。
在我们选择(a)-(d)选项之一后,我们必须乘以列出的 每种方式的选择数加一,以将任何剩余的选项放在右侧 的冰球。 因此,对于选项 (a),只有一种放置方法。 对于选项 (b),每个可能的位置都有两种可能的方式 剩下的一个在冰球的右边。因为只有一个非零值 留在冰球的右侧,总共有两种方式。 对于选项 (c),每个可能的位置都有一种可能的方式 剩下一个在冰球的右侧。同样,因为只有一个非零 剩余价值,总有一种方式。 对于选项 (d),有两种可能的放置方式。 我们选择选项(a)。我们丢弃状态向量并推进冰球:
(1 1 1 0 1 0); 5
由于冰球“覆盖”了第 5 列中的 1,我们只能放置 冰球前的那些。有 (3 take 2) 方法将两个放在三个中 值为 1 的列,因此我们将 3 乘以获得剩余的方法数 可能性。选择第 1 列和第 3 列后(虽然没关系 因为我们已经离开了冰球;这三个中的任何两个都可以),我们删除状态 向量并最后一次推进冰球:
(0 1 0 0 1 0); 6
只有一种方法可以将它们置于这种情况下,因此我们终止 计数为 1。但我们必须考虑所有乘法 方式:1*1*1*1*3*1 = 3。
另一种考虑变化行的方法是从第一个矩阵开始, 关注左下角的 2x3 子矩阵,注意有多少种方法可以 置换该子矩阵的列。由于只有 3 种这样的方式,我们 得到 3 个矩阵。
我认为我理解的内容
此算法计算所有可能的 6x6 数组,每行和每列有 2 个 1,而降对角线没有。
它使用填充 6 个 2 的“state_vector”(表示该列中有多少个 2)和一个表示对角线索引和当前行索引的“puck”作为算法,而不是构造矩阵迭代。
我不明白的地方
-
算法为每一行得出一个值 1,除了 5 被分配一个 3,最后这些值相乘以获得最终结果。这些值应该是每一行的可能位置,但第 1 行有很多可能性,为什么给它一个,为什么算法要等到第 5 行才能计算出所有可能的排列?
任何帮助将不胜感激!
【问题讨论】:
标签: algorithm matrix combinatorics