我正在尝试编写代码来检测矩阵是否为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矩阵的排列,但我除了非常慢的暴力方法外想不到更有效的解决办法。这是规范。
输入:一个n乘n的矩阵M,其条目为1或0。
输入格式:以空格分隔的行。每行一行。例如
0 1 1 1
0 1 0 1
0 1 0 0
1 0 1 1
输出:将矩阵M的行和列进行排列组合,使得M成为一个汉克尔矩阵(如果可能)。汉克尔矩阵具有常数斜对角线(指正斜率的对角线)。
所谓的“排列组合”,是指我们可以对行和列采用不同的置换方式。
非常感谢您提供的任何想法。
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种可能的汉克尔矩阵进行比较,得到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种选择。检查这些排列,我们可以发现以下的Hankel矩阵是原始矩阵的一个排列。
0 1 1 1
1 1 1 0
1 1 0 0
1 0 0 0
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,我们可以忽略反转,因为反转行和列的排列只会将矩阵旋转180度。因此,我们只需要考虑四个排列后的矩阵(行和中3的两种可能顺序和列和中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
不是一个有效的汉克尔矩阵的前两行。这种推理是否容易实现取决于您的编程范式。
请注意,在最坏情况下,这种推理仍然不会留下多项式数量的案例需要用蛮力法穷举。
以下是一些想法。
行和列的置换保持行和列的总和不变:
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
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
应用于原始示例:
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
最后,我提出,每个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
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 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)
注:我建议仅在行或列和的平局情况下使用二进制顺序(#4),而不是替换(#2)中的排序。