【问题标题】:An algorithm to detect permutations of Hankel matrices一种检测汉克尔矩阵排列的算法
【发布时间】:2015-04-07 06:06:29
【问题描述】:

我正在尝试编写代码来检测矩阵是否是 Hankel 矩阵的排列,但除了非常缓慢的蛮力之外,我想不出一个有效的解决方案。这是规格。

输入: 一个 n × n 矩阵 M,其条目为 1 或 0。

输入格式: 空格分隔的行。每行一行。例如

0 1 1 1
0 1 0 1
0 1 0 0
1 0 1 1

输出: M 的行和列的排列,如果可能的话,M 是 Hankel matrix。 Hankel 矩阵具有恒定的斜对角线(正斜对角线)。

当我说排列时,我的意思是我们可以对行的顺序应用一种排列,对列应用一种可能不同的排列。

如果有任何想法,我将不胜感激。

【问题讨论】:

  • 这是一个有趣的问题。我什至看不到多项式时间解!
  • 这个问题的根源是什么?您指定输入格式使其看起来像是来自竞争性编程竞赛或家庭作业。如果是这样,您有额外的信息没有包括在内,您应该自己处理。
  • 也许您可以使用矩阵的某些属性,该属性在排列下是不变的,然后使用它来排除某些矩阵。例如。也许对汉克尔矩阵的行列式有所了解。你可以用它来检测非汉克尔矩阵,这样你就不用再花时间在它们上面了。只是在这里大声思考。
  • @DouglasZare 你说得对,我自己把它作为一个编程挑战发布了,然后我意识到我自己无法提出任何非平凡的算法,所以不适合那个。

标签: algorithm math complexity-theory


【解决方案1】:

不失一般性,我们将假设 0 少于 1。然后,我们可以在 Hankel 矩阵中找到可能为 0 的对角线,从而为我们提供整个矩阵中适当数量的 0。而且,这将为我们提供可能的汉克尔矩阵。从那里,您可以计算每列中 0 的数量,并将其与原始矩阵的列中 0 的数量进行比较。完成此操作后,您可以在其中执行蛮力搜索的空间要小得多:对具有正确数量 0 的列和行进行置换。

示例: OP 建议使用 7 个 0 的 4x4 矩阵。我们需要使用集合{4,3,3,2,2,1,1} 对其进行分区。因此,或分区将是:

  • {4,3}
  • {4,2,1}(其中 2 个矩阵)
  • {3,3,1}
  • {3,2,2}
  • {3,2,1,1}(其中 2 个矩阵)

这给了我们汉克尔矩阵(不包括对称性)

1 1 0 0    1 1 1 0    0 1 1 0    1 1 0 1
1 0 0 1    1 1 0 1    1 1 0 1    1 0 1 0
0 0 1 1    1 0 1 0    1 0 1 0    0 1 0 1
0 1 1 1    0 1 0 0    0 1 0 1    1 0 1 0

1 0 0 1    0 1 1 1    0 1 0 1
0 0 1 1    1 1 1 0    1 0 1 1
0 1 1 0    1 1 0 0    0 1 1 0
1 1 0 1    1 0 0 0    1 1 0 0

原始矩阵的四列中有 3、1、2 和 1 个 0。将其与 7 个可能的 Hankel 矩阵进行比较,我们得出了 2 个可能性

1 1 1 0    0 1 1 1    
1 1 0 1    1 1 1 0    
1 0 1 0    1 1 0 0    
0 1 0 0    1 0 0 0    

现在,只有 4 种可能的排列可以将原始矩阵映射到其中的每一种:基于 2 和 3 个 0 的列,我们只有 1 种选择,但对于 1 0 的列,我们只有 2 种选择,还有 2具有 1 个 0 的行的选择。检查这些排列,我们看到以下 Hankel 矩阵是原始矩阵的排列

0 1 1 1    
1 1 1 0    
1 1 0 0    
1 0 0 0    

【讨论】:

    【解决方案2】:

    这个问题的第一个答案是正确的一件事是排列行和列不会改变行和或列和。

    另一个简单的观察是,在 Hankel 矩阵中,两个连续行之间的行和之差为 -1、0 或 1,并且每种情况都为我们提供了对行的约束。如果差值为 0,则输入变量等于退出变量;否则我们知道哪个是 0,哪个是 1。

    0 1 1 1
    0 1 0 1
    0 1 0 0
    1 0 1 1
    

    具有行和 3、2、1、3。尊重差异要求的顺序是 1 2 3 3 和 3 3 2 1,并且 wlog 我们可以丢弃反转,因为反转行和列排列只会将矩阵旋转180度。因此,我们减少到考虑四个置换矩阵(行和中 3 的两种可能的排序,以及列和中的两种):

    0 0 1 0    0 0 1 0    0 0 0 1    0 0 0 1
    0 0 1 1    0 0 1 1    0 0 1 1    0 0 1 1
    0 1 1 1    1 1 0 1    0 1 1 1    1 1 1 0
    1 1 0 1    0 1 1 1    1 1 1 0    0 1 1 1
    

    我们实际上可以进一步分析,通过观察强制初始行的总和为 1 和 2,我们用总和 3 限制列的顺序,因为

    0 0 1 0
    0 0 1 1
    

    不是汉克尔矩阵的有效初始两行。这种推理是否易于实现取决于您的编程范式。

    请注意,在最坏的情况下,这种推理仍然不会留下多项式的案例来强行通过。

    【讨论】:

      【解决方案3】:

      这里有一些想法。

      1)

      行和列排列保留行和列总和

      1 0 1 0 - 2
      0 0 0 1 - 1  row sums
      1 0 0 0 - 1
      1 1 1 0 - 3
      | | | |
      3 1 2 1
      column sums
      

      无论您以哪种方式排列行,在某些排列中行总和仍将是 {2, 1, 1, 3};列总和将保持不变。反之亦然。 Hankel 矩阵及其排列将始终具有与列和相同的行和集。这使您可以快速测试以排除一组不可行的矩阵。

      2)

      我假设 Hankel 矩阵总是可以以这样的方式排列,即它们的行和列之和按升序排列,结果仍然是 Hankel 矩阵:

      0 1 1 0 - 2         0 0 0 1 - 1
      1 1 0 0 - 2         0 0 1 1 - 2
      1 0 1 1 - 3   -->   0 1 1 0 - 2
      0 0 1 0 - 1         1 1 0 1 - 3
      | | | |             | | | |
      2 2 3 1             1 2 2 3
      

      因此,如果一个矩阵可以置换成Hankel矩阵,那么它也可以置换成行列和升序的Hankel矩阵。也就是说,我们可以通过仅测试行和列和按升序排列的排列来减少测试所需的排列数量。

      3)

      我进一步假设,对于任何两行或多行具有相同和的 Hankel 矩阵,列的每个排列都有一个匹配的行排列,这也会产生一个 Hankel 矩阵。也就是说,如果一个 Hankel 矩阵存在于一个列的排列中,那么它存在于每个列的排列中——因为我们可以简单地将相同的排列应用于相应的行并获得对称的结果。

      结果是我们只需要测试行列的排列,而不是行列.


      应用于原始示例:

      1 0 1 0 - 2       0 0 0 1       0 1 0 0 - 1     0 0 0 1
      0 0 0 1 - 1       1 0 0 0       0 0 0 1 - 1     0 1 0 0
      1 0 0 0 - 1  -->  1 0 1 0  -->  0 0 1 1 - 2 --> 0 0 1 1 = Hankel!
      1 1 1 0 - 3       1 1 1 0       1 0 1 1 - 3     1 0 1 1
      | | | |
      3 1 2 1      permute rows into|   ditto     | try swapping    
                    ascending order | for columns |  top 2 rows
      

      4)

      最后,我假设每个具有相同总和的行和列的 Hankel 矩阵都可以置换为另一个 Hankel 矩阵,其属性是 当读取为二进制数时,这些行和列按升序排列 - 从左到右读取行,从上到下读取列。那就是:

      0 1 1 0       0 1 0 1       0 0 1 1
      1 0 0 1       0 1 1 0       0 1 0 1  New
      1 0 1 0  -->  1 0 0 1  -->  1 0 1 0 Hankel
      0 1 0 1       1 0 1 0       1 1 0 0
      Original       rows         columns
       Hankel      ascending     ascending
      

      如果这是真的(我还没有决定),那么我们只需要创建和测试任何给定输入矩阵的一个排列。这种排列使行和列都按总和的升序排列,在总和相等的情况下,按它们的二进制数解释对它们进行排序。如果这个结果矩阵不是 Hankel,则没有任何排列可以使它成为 Hankel。

      希望这能让你走上算法之路!


      附录:反例?

      尝试@orlp 的例子:

      0 0 1 0     0 0 1 0     0 0 0 1
      0 1 0 1     0 1 0 1     0 1 1 0
      1 0 1 1 --> 0 1 1 1 --> 0 1 1 1
      0 1 1 1     1 0 1 1     1 0 1 1
        (A)         (B)         (C)
      
      • 答:汉克尔原版。行总和为 1、2、3、3;第 3 行和第 4 行不是二进制顺序。
      • B:交换第 3 行和第 4 行。第 3 列和第 4 列不是二进制顺序。
      • C:交换第 3 列和第 4 列。结果是 Hankel 并且满足所有属性。

      尝试@Degustaf 的例子:

      1 1 0 1     0 1 0 0     0 0 1 0
      1 0 1 0     1 0 0 1     0 1 0 1
      0 1 0 0 --> 1 0 1 0 --> 1 0 0 1
      1 0 0 1     1 1 0 1     0 1 1 1
        (A)         (B)         (C)
      
      • A:原始汉克尔矩阵。行总和为 3、2、1、2。
      • B:重新排列,使行和为 1、2、2、3,并且 sum 2 的行按二进制升序排列(即 1001、1010)
      • C:将列总和重新排列为 1、2、2、3,其中总和 2 的两列按顺序(0101、1001)。结果是 Hankel 并且满足所有属性。另请注意,列上的排列与行上的排列相匹配:旧列的新列顺序是 {3, 4, 2, 1},从 A 到 B 的操作相同。

      注意:我建议二进制顺序 (#4) 仅用于行或列总和的平局情况,而不是替代 (#2) 中的排序。

      【讨论】:

      • 谢谢你。很多非常有趣的想法!如果第 3 点是正确的,这不是立即给出使用 stackoverflow.com/questions/20704900/… 的 O(n^2) 时间算法吗?
      • 第 3 点和第 4 点是错误的。 Counterexample.
      • 第 2 点也是 False。具有 2 条长度为 3 的对角线和一条长度为 2 的零对角线的 4x4 矩阵无法转换为建议的形式。
      • 我从你的例子中得到的印象是,你认为任何等于其转置的矩阵都是汉克尔矩阵。这不是问题中给出的定义。
      • @BrianL 您编辑了您的帖子以包含我的反例,试图反驳它。但是你的结果是错误的。这是您的解决方案不是 Hankel 的解释:i.imgur.com/UgvIPM1.png。所有对角线都必须是常数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-06
      • 2015-06-17
      • 1970-01-01
      • 2022-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多