我想通过用LZMA压缩它们并采用压缩比来估计短串(大约一个字长)的Kolmogorov复杂性。
在Python3中最有效的方法是什么?
答案 0 :(得分:2)
修改强>:
我不确定这是否是评估短字符串复杂性的好方法,因为要正确计算字符串的Kolmogorov(K-)复杂度,我们必须考虑用于解压缩字符串的程序的长度。程序的长度(我的Debian笔记本电脑上xz 5.1.0的67k)将压倒短字符串。因此,以下程序更接近于计算K-复杂度上限:
import lzma #For python 2.7 use backports.lzma
program_length = 67000
def lzma_compression_ratio(test_string):
bytes_in = bytes(test_string,'utf-8')
bytes_out = lzma.compress(bytes_in)
lbi = len(bytes_in)
lbo = len(bytes_out)+program_length
ratio = lbo/lbi
message = '%d bytes compressed to %d bytes, ratio %0.3f'%(lbi,lbo,ratio)
print(message)
return ratio
test_string = 'a man, a plan, a canal: panama'
lzma_compression_ratio(test_string)
for n in range(22,25):
test_string = 'a'*(2**n)
lzma_compression_ratio(test_string)
下面的输出显示,对于30 a的字符串,压缩率超过2000,对于重复长度为2 ^ 23的字符串,压缩率低于0.01。这些在技术上是正确的K-复杂性上限,但显然对短字符串没用。程序“print('a'* 30)”的长度为13,字符串'aaaaaaaaaaaaaaaaaaaaa'的K-复杂度上限为0.43(13/30)。
30 bytes compressed to 67024 bytes, ratio 2234.133
4194304 bytes compressed to 67395 bytes, ratio 0.016
8388608 bytes compressed to 68005 bytes, ratio 0.008
16777216 bytes compressed to 69225 bytes, ratio 0.004
原始回答:
@Superbest,这似乎有效,但我不知道它是否最有效:
import lzma
def lzma_compression_ratio(test_string):
c = lzma.LZMACompressor()
bytes_in = bytes(test_string,'utf-8')
bytes_out = c.compress(bytes_in)
return len(bytes_out)/len(bytes_in)
test_string = 'a man, a plan, a canal: panama'
compression_ratio = lzma_compression_ratio(test_string)
print(compression_ratio)