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

2024-04-27 10:27:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在用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 size100dimension20,运行该算法所花费的总时间约为40秒,其中约20秒花费在mutate

现在,我对这个函数进行了优化,使它比上一个版本缩短了约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

但显然,这还不够。我想知道在numpy中是否有一个技巧来移除对r0, r1, r2, and mutant应用元素操作的for循环。关键是只有索引在cross_indxs中的元素才能被使用


Tags: self算法np时间rangerandomcandidatedimensions