python - 在数组的两个不同部分中计算重复整数的最快方法

标签 python algorithm performance

在这段 Python 代码中,

fun 遍历数组 arr 并计算每个部分对的两个数组部分中相同整数的数量。 (它模拟一个矩阵。)这使得 n*(n-1)/2*m 总共进行了比较,给出了 O(n^2) 的时间复杂度。

是否有编程解决方案或重构此问题的方法可以产生相同的结果但降低了时间复杂度?

# n > 500000, 0 < i < n, m = 100
# dim(arr) = n*m, 0 < arr[x] < 4294967311

arr = mp.RawArray(ctypes.c_uint, n*m)

def fun(i):
    for j in range(i-1,0,-1):
        count = 0
        for k in range(0,m):
            count += (arr[i*m+k] == arr[j*m+k])
        if count/m > 0.7:
            return (i,j)
    return ()
  • arr 是共享内存数组,因此出于简单性和性能原因,最好将其保持为只读。

  • arr 被实现为 multiprocessing 的 1D RawArray。根据我的测试,它具有迄今为止最快的性能。使用 numpy 二维数组,例如,如下所示:

    arr = np.ctypeslib.as_array(mp.RawArray(ctypes.c_uint, n*m)).reshape(n,m)
    

    将提供矢量化功能,但会增加一个数量级的总运行时间 - 250 秒对比 n = 1500 时的 30 秒,总计 733%

最佳答案

由于您根本无法更改数组特性,我认为您被 O(n^2) 困住了。 numpy 会获得一些矢量化,但会改变其他共享数组的访问权限。从最里面的操作开始:

    for k in range(0,m):
        count += (arr[i][k] == arr[j][k])

将其更改为单行分配:

    count = sum(arr[i][k] == arr[j][k] for k in range(m))

现在,如果这真的是一个数组,而不是列表的列表,使用数组包的矢量化来简化循环,一次一个:

    count = sum(arr[i] == arr[j])   # results in a vector of counts

您现在可以返回 j 索引,其中 count[j]/m > 0.7。请注意,实际上没有必要为每个返回 i:它在函数中是常量,并且调用程序已经具有该值。您的数组包可能有一对可以返回这些索引的矢量化索引操作。如果您使用的是 numpy,那么可以很容易地在本网站上查找它们。

关于python - 在数组的两个不同部分中计算重复整数的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52636289/

相关文章:

c++ - 什么样的优化会提高我的表现?

c# - 3SUM - O(n^2 * log n) 比 O(n^2) 慢?

python - 与其按键读取字典,不如按值读取 (mydict[key] = value >>> mydict[value] = key)

python - Django 嵌套内联 TemplateDoesNotExist

python - tkinter:在父级中显示的 Toplevel 中的框架

c++ - 代码的最优解,使其可以执行最多 10^18 的计算

algorithm - 线条简化图像处理

通过分布式 jmeter 实例和 bamboo 进行性能测试

python - 检查对象列表是否包含具有特定属性值的对象

python - Dijkstra 的 SPF 算法中两个顶点(节点)实例之间的类型错误