当前位置:  开发笔记 > 人工智能 > 正文

如何计算线性时间内的排列,扭曲

如何解决《如何计算线性时间内的排列,扭曲》经验,为你挑选了1个好方法。

我在Java中有一个资源调度问题需要对事物进行排序,但是对于哪些资源可以彼此相邻存在限制.一个很好的类比是一串"数字",其中只有某些数字可以彼此相邻.我的解决方案是递归的,适用于小字符串,但运行时间是O(X ^ N),其中X是可能的数字(基数),N是字符串的长度.它很快变得无法管理.

使用下面的兼容性矩阵,以下是允许字符串的一些示例
长度为1:0,1,2,3,4
长度为2:02,03,14,20,30,41
长度为3:020,030, 141,202,203,302,303,414

     0  1  2  3  4
   ---------------------
0|  0  0  1  1  0
1|  0  0  0  0  1
2|  1  0  0  0  0
3|  1  0  0  0  0
4|  0  1  0  0  0

我计算所有长度为N的字符串的解决方案是从一个空字符串开始,置换第一个数字,并对所有长度为N-1的字符串进行递归调用.递归调用检查添加的最后一个数字,并尝试可以在该数字旁边的所有排列.有一些优化,所以我不会尝试每次都进行00,01,04,例如02,03,但是从基数5(示例)扩展到基数4000时,性能仍然很差.

除了试图列举所有排列之外,还有什么想法更好地计算排列?



1> Markus Jarde..:

如果你只想要一定长度的字符串数,你可以将兼容性矩阵与它自己相乘几次,并将它的值相加.

n = 字符串长度
A = 可能字符串的兼容性矩阵
= A n -1的总和

几个例子:

n = 1
| 1 0 0 0 0 |
| 0 1 0 0 0 |
| 0 0 1 0 0 |
| 0 0 0 1 0 |
| 0 0 0 0 1 |
sum: 5

n = 3
| 2 0 0 0 0 |
| 0 1 0 0 0 |
| 0 0 1 1 0 |
| 0 0 1 1 0 |
| 0 0 0 0 1 |
sum: 8

n = 8
| 0 0 8 8 0 |
| 0 0 0 0 1 |
| 8 0 0 0 0 |
| 8 0 0 0 0 |
| 0 1 0 0 0 |
sum: 34

原始矩阵(行i,列j)可以被认为是以符号i开始的字符串的数量,并且其下一个符号是符号j.或者,您可以将其视为长度为2的字符串数,以符号i开头,以符号j结尾.

矩阵乘法保留了这个不变量,因此在取幂后,A n -1将包含以符号i开头,长度为n,以符号j结尾的字符串数.

请参阅维基百科:通过平方算法来更快地计算矩阵幂.

(感谢stefan.ciobaca)

这个具体案例简化为公式:

可能的字符串的数目 = ˚F(Ñ)= 4 +Σ ķ = 1 .. Ñ 2 ķ -1/2 = ˚F(Ñ -1)+ 2 Ñ -1/2

n       f(n)
----    ----
   1       5
   2       6
   3       8
   4      10
   5      14
   6      18
   7      26
   8      34
   9      50
  10      66


)= 4 +Σ
-1)+ 2
这很酷,但不是关于限制*排列*的大小的问题?这并没有强制数字最多可以使用一次的约束,这就是我所说的'置换'.哦,等等,'202'就是一个例子.那么问题只是一个令人困惑的表达.
推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有