我正在尝试提出一种比较二进制数组(从长度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,但是“位密度”是指完全不同的东西!我将继续努力,但同时,我想询问是否有人知道我不知道算法的名称。
答案 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")
初始化为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的密度越好。