定义:数组A(a1,a2,...,an)
>=
比B(b1,b2,...bn)
a_i>=b_i
i
1
n.
[1,2,3] >= [1,2,0]
[1,2,0] not comparable with [1,0,2]
[1,0,2] >= [1,0,0]
B
A >= B
A
O(n^2)
import numpy as np
import time
import random
def filter_minimal(lst):
n = len(lst)
to_delete = set()
for i in xrange(n-1):
if i in to_delete:
continue
for j in xrange(i+1,n):
if j in to_delete: continue
if all(lst[i]>=lst[j]):
to_delete.add(i)
break
elif all(lst[i]<=lst[j]):
to_delete.add(j)
return [lst[i] for i in xrange(len(lst)) if i not in to_delete]
def test(number_of_arrays,size):
x = map(np.array,[[random.randrange(0,10) for _ in xrange(size)] for i in xrange(number_of_arrays)])
return filter_minimal(x)
a = time.time()
result = test(400,10)
print time.time()-a
print len(result)
numpy.all
all
1}}
例如:
{{1}}
我有一个列表,其中包含大量此类数组(大约10000,但可以更大)。数组的元素是正整数。我需要删除此列表中比至少其中一个数组大的所有数组。换句话说:如果存在{{1}} {{1}} {{1}},则删除{{1}}。
这是我当前的{{1}}方法,这种方法非常慢。我只是将每个数组与所有其他数组进行比较,如果它更大则将其删除。有没有办法加快速度。
{{1}}
P.S。我注意到使用{{1}}而不是内置python {{1}}会大大减慢程序的速度。可能是什么原因?
答案 0 :(得分:1)
可能不是你要求的,但这应该让你开始。
import numpy as np
import time
import random
def compare(x,y):
#Reshape x to a higher dimensional array
compare_array=x.reshape(-1,1,x.shape[-1])
#You can now compare every x with every y element wise simultaneously
mask=(y>=compare_array)
#Create a mask that first ensures that all elements of y are greater then x and
#then ensure that this is the case at least once.
mask=np.any(np.all(mask,axis=-1),axis=-1)
#Places this mask on x
return x[mask]
def test(number_of_arrays,size,maxval):
#Create arrays of size (number_of_arrays,size) with maximum value maxval.
x = np.random.randint(maxval, size=(number_of_arrays,size))
y= np.random.randint(maxval, size=(number_of_arrays,size))
return compare(x,y)
print test(50,10,20)
答案 1 :(得分:0)
首先,我们需要仔细检查目标。我们删除任何&gt;的数组是真的吗?任何其他数组,甚至是删除的数组?例如,如果A> B和C> A和B = C,那么我们是否只需删除A或A和C两者?如果我们只需要删除INCOMPATIBLE数组,那么这是一个更难的问题。这是一个非常困难的问题,因为这组数组的不同分区可能兼容,因此您遇到了找到最大有效分区的问题。
假设容易出问题,更好的定义问题的方法是你想要保留所有至少有一个元素的数组&lt;所有其他数组中的相应元素。 (在硬问题中,它是其他KEPT数组中的相应元素。我们不会考虑这个。)
第1阶段
要解决此问题,您要做的是将数组排列在列中,然后对每行进行排序,同时保持数组的键以及每个数组行到位置的映射(POSITION列表)。例如,您最终可能会在第1阶段得到如下结果:
第1行:B C D A E
第2行:C A E B D
第3行:E D B C A
意味着对于第一个元素(第1行),数组B的值为&gt; = C,C> = D等等。
现在,对此矩阵的最后一列进行排序和迭代(示例中为{E D A})。对于每个项目,检查元素是否小于其行中的上一个元素。例如,在第1行中,您将检查E&lt; A.如果这是真的,您立即返回并保留结果。例如,如果E_row1&lt; A_row1然后您可以保留数组E.只有当行中的值相等时,您才需要进行第2阶段测试(见下文)。
在显示的示例中,您将保留E,D,A(只要他们通过上述测试)。
第二阶段
这将离开B和C.为每个排序POSITION列表。例如,这将告诉您具有B的最小位置的行是第2行。现在直接比较B和它下面的每个数组在mininum行,这里是第2行。这里只有一个这样的数组,D。 B和D之间的直接比较。这表明B
现在我们对C做同样的事情。在C的情况下,我们只需要进行一次直接比较,而A.C支配A,所以我们不保留C.
请注意,除了测试最后一列中没有出现的项目之外,我们还需要测试第1阶段中具有相同性的项目。例如,假设第1行中D = A = E.在这种情况下,我们必须对最后一列中涉及数组的每个相等进行直接比较。因此,在这种情况下,我们将E与A和E直接比较为D.这表明E支配D,因此不保留E.
最终结果是我们保留A,B和D. C和E被丢弃。
此算法的整体性能在阶段1中为n2 * log n +阶段2中的{n下限,n * log n - 上限}。因此,最大运行时间为n2 * log n + nlogn且最小运行时间时间是n2logn + n。请注意,算法的运行时间为n-cubed n3。由于你比较每个矩阵(n * n),每个比较是n个元素比较= n * n * n。
一般来说,这比蛮力方法要快得多。大部分时间都用于对原始矩阵进行排序,这或多或少是不可避免的任务。请注意,您可以通过使用优先级队列而不是排序来改进我的算法,但生成的算法会复杂得多。