在 numpy 数组中按元素应用操作
Applying operation element-wise in numpy array
我目前正在 python 中实施差分进化算法,在较低维度上工作时一切都很好,但是,当我开始增加搜索维度时 space 所花费的时间到 运行 算法呈指数增长。在做了一些分析后,我发现大部分时间都花在了变异函数上,如下所示,
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])
现在,对于 100
的 population size
和 20
的 dimension
,算法花费的总时间 运行 大约是 ~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
中的元素。
试试这个:
mutant[cross_indxs] = (r0[cross_indxs] + self.F[cross_indxs] * (r1[cross_indxs] - r2[cross_indxs])).clip(self.range[0],self.range[1])
我目前正在 python 中实施差分进化算法,在较低维度上工作时一切都很好,但是,当我开始增加搜索维度时 space 所花费的时间到 运行 算法呈指数增长。在做了一些分析后,我发现大部分时间都花在了变异函数上,如下所示,
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])
现在,对于 100
的 population size
和 20
的 dimension
,算法花费的总时间 运行 大约是 ~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
中的元素。
试试这个:
mutant[cross_indxs] = (r0[cross_indxs] + self.F[cross_indxs] * (r1[cross_indxs] - r2[cross_indxs])).clip(self.range[0],self.range[1])