簡體   English   中英

對所有可能組合執行操作的最快方法

[英]Fastest approach for performing operations on all possible combinations

我正在尋找最快的方法來獲得列表中所有可能的配對組合之間的最小絕對差異。

我做了兩個解決方案,但在持續時間內沒有一個是可以接受的。

arr = [x for x in range(10000)]
minAbsDiff1(arr)
minAbsDiff2(arr)

def absDiff(elem):
    return abs(elem[0]-elem[1])

# first solution takes 5.96 sec
def minAbsDiff1(arr):
    seq = itertools.combinations(arr, 2)
    m = min(seq, key=absDiff)
return absDiff(m)

# second solution takes 6.96 sec
def minAbsDiff2(arr):
    seq = itertools.combinations(arr, 2)
    test = [abs(tup[0]-tup[1]) for tup in seq]
return min(test)

輸入示例:[3, -7, 0]

所有組合:(3, -7), (3, 0), (-7, 0)

Output 最小絕對差異:3

解釋:3 - 0 = 3

解決方案

另一種可能為您提供更快結果的方法:

首先對值進行排序並對其進行迭代以找到最小差異:

def minAbsDiffSorted(arr):
    sorted_arr = sorted(arr)
    min_val = sorted_arr[-1] - sorted_arr[0]
    for i, j in zip(sorted_arr[:-1], sorted_arr[1:]):
        min_val = min(min_val, j - i)
    return min_val

對 numpy 執行相同操作甚至更快:

import numpy as np
def minAbsDiffNumpy(arr):
    return np.diff(np.sort(np.array(arr))).min()

機制

要處理的數組:

import numpy as np
import random
arr = np.array([random.randint(0, 100) for _ in range(20)])
>>>
array([55, 76, 88,  2, 68,  9, 24, 50, 15, 86, 19, 31, 80, 39, 14, 48, 32,
       32, 35, 26])

讓我們對數組進行排序:

arr = np.sort(arr)
>>>
array([ 2,  9, 14, 15, 19, 24, 26, 31, 32, 32, 35, 39, 48, 50, 55, 68, 76,
       80, 86, 88])

獲取值之間的差異:

np.diff(arr)
>>>
array([ 7,  5,  1,  4,  5,  2,  5,  1,  0,  3,  4,  9,  2,  5, 13,  8,  4,
        6,  2])

您取這些差異中的最小值,在本例中為 0。這相當於原始數組的成對組合的最小距離。

時代

以下是我機器上的相應時間:

%%timeit
minAbsDiff1(arr)
17.3 s ± 438 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
minAbsDiff2(arr)
19.1 s ± 1.16 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit
minAbsDiffSorted(arr)
7.85 ms ± 498 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
minAbsDiffNumpy(arr)
444 µs ± 3.73 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

解釋

關於其背后的原因,請參閱@Yves Daoust 詳細解釋。

是的,使用組合也可以對結果進行排序。 但是,主要的操作不是排序,而是自己進行組合。

在這里您可以閱讀有關itertools.combinations時間復雜度的更多信息。

與此相比,這里最昂貴的操作是排序,僅此而已。

如果您對元素進行越來越多的排序,則最接近每個元素的是前一個或下一個。 因此,嘗試每一對連續的對就足夠了。

這樣做,您可以用 O(n²) 復雜度換取 O(n),這是一個顯着的改進。 除非您的數據允許基於非比較的排序,否則排序將花費 O(n log n) 並主導成本(仍然優於 O(n²))。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM