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

时间:2019-11-01 00:48:37

标签: python numpy differential-evolution

我目前正在用python实现差分进化算法,当在较小尺寸下工作时一切都很好,但是,当我开始增加搜索空间的尺寸时,运行该算法所需的时间呈指数增长。经过一些分析后,我发现大部分时间都花在了突变功能上,如下所示,

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])

现在,对于population size的{​​{1}}和100的{​​{1}},运行算法所需的总时间约为40秒,其中约20秒dimension中花费了几秒钟。

现在,我已经取消了对该功能的优化,以使其比以前的版本缩短了约3秒。

20

但是显然,这还不够。我想知道mutate中是否有技巧可以删除在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 上应用元素操作的for循环。要注意的是,只能使用索引在numpy中的元素。

1 个答案:

答案 0 :(得分:0)

尝试一下:

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