如何在5x5矩阵中分配5位数字

时间:2014-06-17 02:22:41

标签: math matrix numbers distribution diagonal

我有98000个5位数字,从00001到98000.我需要在14000个5x5矩阵中分发这98000个数字。

矩阵单元格必须只包含0到9之间的数字。

每个矩阵必须从98000接收7个数字:每行一个数字,对角线两个。

所有98000个数字必须在所有14000个矩阵中分发,不得重复。

分布不能感觉它是顺序的,它必须显得“随机”。

以下是一个例子:

0 1 2 3 0
7 6 5 4 3
0 0 8 1 2
3 7 5 6 0
4 5 5 0 0

Line 1: Number 01230
Line 2: Number 76543
Line 3: Number 00812
Line 4: Number 37560
Line 5: Number 45500
Main Diagonal (from top-left to bottom-right): 06860
Secondary Diagonal (from bottom-left to top-right): 47840

另一个例子:

3 9 4 0 5
1 3 2 0 9
0 0 0 0 1
9 7 4 5 4
1 2 7 7 8

Line 1: Number 39405
Line 2: Number 13209
Line 3: Number 00001
Line 4: Number 97454
Line 5: Number 12778
Main Diagonal (from top-left to bottom-right): 33058
Secondary Diagonal (from bottom-left to top-right): 17005

数学上可行吗?我的意思是,可以在14000个矩阵中分配所有98000个数字而不重复? 如果是,我该如何编写算法来进行分发?

我尝试用C#编写程序来完成这项任务,但我找不到一个好的策略来做这件事。我的程序总是试图填写已填充的数字。

提前致谢!

编辑:

在数学StackExchange上发布相同的question,以防您想要关注。

2 个答案:

答案 0 :(得分:1)

这是一个非确定性但易于实现的算法:

生成从1到98000的数字的随机排列。 出于这种排列,只需要前70000 (这是14000 * 5,这足以构建14000个5x5矩阵。)

创建一个大小为98000的布尔数组,最初都等于false。 该数组将用于标记哪些数字已在使用中。 设这个数组表示为F.

然后,迭代选定的70000个数字,一次一个数字。 对于考虑的每个5位数字N,标记F [N] =真。

接下来,迭代相同的选定70000数字, 但现在按顺序考虑一次五个数字。 这五个数字构成一个5x5矩阵。 它保证矩阵的行不会重复, 但是没有关于对角线的保证。 此外,无法保证对角线数字, 让它们称为D1和D2,小于98000,或者它们不相等。

那么,让我们检查对角线数字。 提取每个对角线对应的数字, 并将它们组合成5位数字D1和D2。 如果D1和D2中的任何一个大于98000,或者它们相等, 随机排列不会导致解决方案, 你需要从头开始,现在有另一个随机排列。 其他人,继续检查对角线数字。 现在,检查F数组:如果F [D1]和F [D2]中的任何一个为真, 你有重复,你必须从另一个随机排列开始。 如果F [D1]和F [D2]都为假,则将它们设置为true并继续下一个矩阵。 如果你足够幸运,你可能会发现一个很好的排列 (确保将其写入文件,因为上述随机搜索可能需要一些时间, 在搜索后数小时(数周?)之后失去排列将是一种遗憾。

如果你设法进入这个阶段,你的对角线数字和所有行都是唯一的, 并且所有都是从1到98000.这意味着您使用了所有数字 从1到98000.也就是说,剩下的98000-70000 = 28000个数字都没有丢失。

我不确定是否有解决方案:可能是您的问题 过度约束(即所有排列都不能满足您的条件)。 但是,至少,你可以从这个随机搜索开始。 虽然它正在进行中,但您可以考虑更好的确定性算法;)

答案 1 :(得分:1)

请注意答案,但不适合发表评论,这可能有所帮助。我想快速指出另一种看待问题的方法。

为了简化说明,我将使用以下矩阵作为模板。

A # # # B
# C # D #
# # E # #
# F # G #
H # # # I

此模板根据每行中的对角线数字进行分组:

行 - 对角线分组:

Row 1: (A,B)
Row 2: (C,D)
Row 3: (E)
Row 4: (F,G)
Row 5: (H,I)

您的矩阵受到对角线数量的约束,因为每个行选择都会约束每个对角线(字母)的数字。但是,它仍然留下了3-4个未受训练的数字。可以使用那些未训练的数字来至少在早期改变对角线。虽然,我认为最终这将是相当困难的,除非你能找到一些较小的设置大小的有用模式,可以转换为更大的设置大小。但是,这至少应该有助于更有效地搜索给定行的有效数字。

编辑:

我怀疑是否可以这样做,那么可能必须遵循关于如何分配数字的模式,但很难说它会是什么。

您目前正在尝试找到一个解决方案,对于数字从1到K的D位数,其中K = 98000,D = 5,K是7的倍数。也许您应该尝试慢慢建立一个列表解决方案。对于i的前几个左右的值,也许你应该对K = i * 7蛮力。如果他们是任何解决方案,那么它应该给你一些关于你可以利用来解决这个问题的模式的想法。使用那些你应该能够找到更高倍数为7的解决方案,直到你最终达到i = 14000。它也可能有助于确定哪些7的倍数可能没有解决方案。