【发布时间】:2021-05-12 19:07:55
【问题描述】:
假设我有一个任意大小 (n, m) 的二维矩阵 M。现在我想有效地对 M 中的所有行与 M 中的所有其他行进行一些向量操作。就我而言,我想在每一行之间计算按位异或。
我们所知道的是没有必要计算 xnor(x, y) 和 xnor(y, x),计算其中之一就足够了。此外,就我而言,不需要计算 xnor(x, x)。我知道这个问题的两种解决方案:
def xnor(p, q):
return abs(p-1) * abs(q-1) + (p * q)
def solution_one(M):
return xor(M[:, None], M).all(axis=2)
def solution_two(M):
n = M.shape[0]
results = np.zeros((n, n))
# Upper triangular indices of
ii, jj = np.triu_indices(n, 1)
for i, j in zip(ii,jj):
results[i,j] = xnor(M[i], M[j]).all(axis=0)
return results
用我们得到的一些任意大矩阵来运行这两者,得到解决方案一
# 100x100
%timeit solution_one(M)
# 3.55 ms ± 73.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# 500x500
%timeit solution_one(M)
# 1.36 s ± 59.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# 1000x1000
%timeit solution_one(M)
# 27.4 s ± 603 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
解决方案二
# 100x100
%timeit solution_two(M)
# 29.5 ms ± 535 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 500x500
%timeit solution_two(M)
# 1.06 s ± 41.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# 1000x1000
%timeit solution_two(M)
# 5.58 s ± 95.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
如您所见,对于较小的实例,solution_one 比 solution_two 快,但对于较大的实例则相反。
我们可以看到solution_one 正在执行n x n 计算,而solution_two 将执行(正如 Naphat Amundsen 在 cmets 中提到的)((n x n) - n) / 2。有更好的解决方案吗?是否可以以某种方式构造一个新的 M 矩阵,使得解决方案更接近((n x n) - n) / 2 计算?
【问题讨论】:
-
您好,这是一个有趣的问题。正如你所说,我有点想知道
solution_two是如何完成超过一半的(n x n)的。不是在做((n x n) - n) / 2吗? -
是的,您是对的,感谢您的关注!我会更新我的问题。当我应该做
triu时,我做了tril