简体   繁体   English

在 numpy 数组中按元素应用操作

[英]Applying operation element-wise in numpy array

I'm currently implementing a differential evolution algorithm in python, and all is great when working in lower dimensions, however, when I start increasing the dimensions of the search space the time taken to run the algorithm increases exponentially.我目前正在 python 中实现差分进化算法,在较低维度上工作时一切都很好,但是,当我开始增加搜索空间的维度时,运行算法所需的时间呈指数增长。 After doing a little profiling I found that most of the time is spent in the mutation function, which is as follows,做了一点profiling后发现大部分时间都花在了突变function上,如下,

def _mutate(self, candidate: int) -> np.ndarray:
    # r0, r1, & r2 are np.ndarrays of shape (dimension,)
    r0, r1, r2 = self._select_samples(candidate)

    # mutant is an np.ndarray of shape (dimension,)
    mutant = np.copy(self.population[candidate])

    j_rand = int(np.random.uniform() * self.dimensions)
    for j in range(self.dimensions):
        if np.random.uniform() < self.cr or j == j_rand:
            # bound the mutant to the search space
            mutant[j] = np.clip(r0[j] + self.F * (r1[j] - r2[j]),
                                self.range[0], self.range[1])

Now, for a population size of 100 and a dimension of 20 , the total time taken to run the algorithm is about ~40 seconds, ~20 of those seconds are spent in mutate .现在,对于100population size20dimension ,运行该算法的总时间约为 40 秒,其中约 20 秒用于mutate

Now, I have chipped away at this function optimizing it to shave off about ~3 seconds from the previous version.现在,我已经对这个 function 进行了优化,使其比以前的版本缩短了大约 3 秒。

def _mutate_2(self, candidate: int) -> np.ndarray:
    r0, r1, r2 = self._select_samples(candidate)
    mutant = np.copy(self.population[candidate])
    j_rand = np.random.randint(self.dimensions)
    cross_indxs = np.flatnonzero(np.random.rand(self.dimensions) < self.cr)
    cross_indxs = np.append(
        cross_indxs, [j_rand]) if j_rand not in cross_indxs else cross_indxs

    for j in cross_indxs:
        mutant[j] = np.clip(r0[j] + self.F * (r1[j] - r2[j]), self.range[0],
                            self.range[1])

    return mutant

But obviously, that is still not sufficient.但显然,这还不够。 I am wondering if there may be a trick in numpy to remove the for loop applying element-wise operations on r0, r1, r2, and mutant .我想知道numpy中是否有一个技巧来删除 for 循环,在r0, r1, r2, and mutant上应用逐元素操作。 The catch is that only elements whose indices are in cross_indxs can be used.问题是只能使用索引在cross_indxs中的元素。

Try this:尝试这个:

mutant[cross_indxs] = (r0[cross_indxs] + self.F[cross_indxs] * (r1[cross_indxs] - r2[cross_indxs])).clip(self.range[0],self.range[1])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM