我有一个(nxn)个矩阵X,一个(nx1)列向量v和一个取决于v的标量a。
我必须为所有2 ^ n个可能的0-1向量v评估X * v * a。
最低工作代码如下。我的第一次尝试是一种非常幼稚的方法,而第二次尝试则是更Python化的。第一次尝试(5.5s-6.0s)大约是我第二次尝试(3.5s-4.0s)的1.5倍。在两种情况下,如果我将N都增加1,则两种方法的执行时间大约会加倍。 (这是有道理的,向量的数目随着N的增加而增加一倍。)
不幸的是,我需要计算N = 33,这将比使用我的最佳编码的工作示例(约32小时)花费大约32768倍的时间。时间的乘数增加是不可避免的,但是在工作示例中,没有人看到我可以在执行时间上减少更多的地方吗?
import numpy as np
import itertools
import time
N = 18 # the number of nodes
n = 2**N-1 # the number of 0-1 vectors
X = np.random.rand(N,N)
then = time.time()
##############################################################
### First attempt iterates over all possible 0-1 vectors
### decimal -> binary string -> binary vector -> weighted vector -> transformed vector
##############################################################
S0 = np.zeros(N)
for i in range(n):
str = bin(i)[2:].zfill(N)
v = np.asarray([int(char) for char in str])
exp1 = str.count('1')
exp0 = N - exp1
v_wtd = v * (0.9**exp0) * (0.1**exp1)
S0 = S0 + np.dot(X,v_wtd)
now1 = time.time()
print("The first run took ",now1-then, "seconds.")
##############################################################
### Second attempt uses list comprehension to create all possible 0-1 vectors
### another comprehension is used to weight them, transform them, and finally sum them
##############################################################
lst2 = [list(i) for i in itertools.product([0, 1], repeat=N)]
S1 = np.sum([np.dot(X,v)*(0.9)**(N-sum(v))*(0.1)**(sum(v)) for v in lst2], axis=0)
now2 = time.time()
print("The second run took ",now2-now1, "seconds.")
print(S0-S1) # a check to ensure both calculations are the same, should be a zero vector