这里有一些想法。
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) 中的排序。