有没有一种有效的方法来计算比特流中1s的密度?

时间:2018-10-17 07:52:02

标签: algorithm

我正在尝试提出一种比较二进制数组(从长度1到长度1000)以确定相对密度为1的好方法。

01010101的密度将小于00011011,因为1的扩展程度更大。

同样,总数很重要。因此,尽管11111111均为100%1,但比11更差(更高的值)。 (将第二个填充到00000011可以解决此问题,但会导致以后出现问题。)

该算法将用于嵌套循环(遗传程序中的计分方法),因此我目前对O(n ^ 2)时间和O(n)空间的求解不会削减它!

到目前为止,我将使用以下数据(根据在第一代中将被剔除的可怕算法)来解释我目前使用的两种肮脏方法:

Stream      Result A   Result B (8+7+6+5+4+3+2)
A: 001000       1.17          7  1+1+1+1+1+1+1
B: 000          0.00          0  0+0+0+0+0+0+0
C: 1011011      5.57         25  5+5+4+4+3+2+2
D: 1011         4.25         19  3+3+3+3+3+2+2
E: 1            2.00          7  1+1+1+1+1+1+1
F: 1001010      2.29         16  3+3+3+2+2+2+1
G: 11111111    16.00         35  8+7+6+5+4+3+2
H: 1001001      2.29         14  3+3+2+2+2+1+1
I: 10101        2.80         17  3+3+3+3+2+2+1

结果A::计算方法是1的平方数除以数字总数,再加上连续的1的最大大小。因此,对于 C ,7个中的5个为1,最大分组为2,所以2+(5 * 5/7)。这种方法的问题是 F H 是匹配的,尽管 F 更“扎堆”了。好处是它可以在O(n)中运行,并通过保持运行总计为O(1)[4个变量:num1s,totalnum,maxBunch,bunkSoFar]的空间。

结果B:计算从n =最大大小开始(在本例中为8,但在我的程序900中),并计算通过将n分组可以捕获的最大1数。连续的数字在一起。然后通过将n-1个连续的数字组合在一起将其添加到捕获的最大值中。我停止2的分组,因为1的分组对于任何非零数组将始终返回1。这样做的好处是可以正确地将 H 设置为比 F 低的分数,但是需要整个阵列所需的时间O(n ^ 2)和空间O(n)被存储为更多的数字被添加。 (压缩可以帮助占用空间,但时间成本会使其无法承受。)

结论 我正在寻找一种比结果B更有效的方法,但可以提供比结果A更详细的排序。我尝试使用google,但是“位密度”是指完全不同的东西!我将继续努力,但同时,我想询问是否有人知道我不知道算法的名称。

1 个答案:

答案 0 :(得分:0)

代码在python3中,方法是从最终值读取0减去最终值并读取1。考虑到1和0的接近度,对于每个连续的0,您都减去一个较大的数字,对于每个连续的1,您都添加一个较大的数字。例如5位数字:

00011将计算-1,-2,-3,+ 1和+2

同时

00101将计算-1。 -2,+ 1,-1和+1

使用str = str.lstrip("0")

代替前导0,而不是填充前导0。

初始化为sum = 8 - len(bits)(在您的情况下为sum = 900 - len(bits))。

然后sum = -((sum * (sum + 1)) / 2)

然后您可以遍历O(n)并使用以下for循环使用额外的空间为O(1):

    prev = 0
    prev_a = '0'
    for x in str:
        if x == '0':
            prev -= 1
            if prev_a == '0':
                sum += prev
            else:
                sum += -1
                prev = -1
            prev_a = '0'
        else:
            prev += 1
            if prev_a == '1':
                sum += prev
            else:
                sum += 1
                prev = 1
            prev_a = '1'
    print(str, sum)  

这给出的输出为:

10000000 :   -27.0
001000 :     -15.0
000 :        -36.0
1011011 :    4.0
1011 :       -7.0
1 :          -27.0
1001010 :    -3.0
11111111 :   36.0
1001001 :    -4.0
10101 :      -5.0

您可以在末尾加36,以获得所有正值。

数字越大,表示1s的密度越好。