@
Das S、Suganthan P N.差別化進化:最先端の調査[J]。IEEE Transactions on Evolutionary Computation、2011、15(1):4-31。
@article {das2011differential、
title = {Differential Evolution:A Survey of the State of the Art}、
author = {Das、Swagatam and Suganthan、PN}、
journal = {IEEE Transactions on Evolutionary Computation}、
volume = {15 }、
number = {1}、
pages = {4--31}、
year = {2011}}
一般的な
これは、Differential Evolution(DE)のレビューです。私はこの種の方法に慣れていないため、記録しか作成できません。
主な内容
次の質問を検討してください。
ここで、\(X =(x_1、\ ldots、x_D)\)です。
私の知る限り、勾配降下法など、ベイズ最適化はこのような問題に対処するために使用できますが、進化的アルゴリズム(EA)、進化的プログラミング(EP)、進化戦略(ES)、遺伝的アルゴリズム(GA)などもあります。そして、この記事で紹介されたDE(基本は後で理解されません)。
DE /ランド/ 1 / binに
最初に元のフォームを与え、それをDE / rand / 1 / binと呼びます:
INPUT:スケール係数\(F. \) 、クロスオーバー率(\ \のCr) 、集団サイズ\(NP \) 。
1:注文\(G = 0 \) 、およびランダム初期化\(P_G = \ {X_ { 1、 G}、\ ldots、X_ {NP、G} \} \)。
2:停止基準が満たされていない場合
- 以下のための\(iは1を=、\ ldots、NP \)を実行します。
- 変異ステップ:
- クロスオーバーステップ:次のように生成します\(U_ {i、G} =(u_ {1、i、G}、\ ldots、u_ {D、i、G})\)
- 選択ステップ:
- のために終了します。
- \(G = G + 1 \)。
終わりながら。
ここで、\(X_ {i、G)=(x_ {j、i、G}、\ ldots、x_ {D、i、G})\)、\(j_(rand)\)はランダムに生成されます\([1、D] \)整数、\(U \)が\(X \)、\(X_ {r_1 ^ i、G}、X_ {r_2 ^ i、G }、X_(r_3 ^ i、G)\)は\(P_G \)からランダムに選択され、異なります。
以下では、多くのバリアントを見つけることができ、これらのバリアントは、多くの場合、変異ステップとクロスオーバーステップのバリアントです。
DE /?/?/?
DE /ランド/ 1 / EXP
これは、クロスオーバーステップのバリアントです。
\([1、D] \)から整数\(n \)および\(L \)をランダムに抽出し、次に
\(L \)は次の手順で生成できます
- \(L = 0 \)
- while \(\ mathrm {rand} [0,1] \ le Cr \) and \(L \ le D \):
ドイツ/最高/ 1
ここで、\(X_ {best、G)\)は\(P_ {G} \)の最適点です。
ドイツ/最高/ 2
DE /ランド/ 2
ハイパーパラメーターの選択
よく見ていませんでしたが、おおまかにいくつかの箇所を紹介しているだけで、まだまだ調べておきたいことがたくさんあります。
\(F \)選択
推奨される\([0.4、1] \)(最高0.5)、推奨される\(0.6 \)、推奨される\([0.4、0.95] \)(最高0.9)。
次のようないくつかの適応オプションもあります
私はもっと困惑しています。\(| \ frac {f _ {\ max}} {f _ {\ min}} | \)は1以下ではありません
その中で、\(F_l \)と\(F_u \)はそれぞれ\(F \)の下限と上限です。
\(NP \)選択
いくつかの推奨事項\([5D、10D] \)、いくつかの推奨事項\([3D、8D] \)。
\(Cr \)選択
いくつかの推奨事項\([0.3、0.9] \)。
また
一部の継続的なバリアント
あ
もし(\ mathrm {RAND} [0,1] <\ガンマ\)\(\(\ガンマ\)が与えられます)。
そうでなければ
B
前記\(K_I \)が与えられると、\(F.「= K_I \ CDOT F. \) 。
C
D
それは考えると、ある(X \)\時間を、また、その抗考慮する必要があります\(A + BX \)を、と仮定して([A、B]でX- \ \)\、(\ [A、B])\に私たちのために\(X \)の固定範囲の反相似構造。
E
その中で、\(X_ {n_ {best}、G} \ )は\(X_ {i、G} \)の\(n \)の最近傍の中で最も有利な点を表し、[ik、iの\(p、q \ + k] \)。
それらの中で\(X_ {g_ {best}、G} \)は\(P_G \)の中で最高です。
G
複雑な環境での残りのアプリケーションは記録されません(その方法について話してください)。
いくつかの欠点
- 高次元の問題は簡単に処理できません。
- いくつかの問題にだまされがちですが、今ではローカルの最適なソリューションになっています。
- 分解できない関数にはあまり適していません。
- 多くの場合、パスは長すぎません(つまり、探索が不十分です)。
- 収束の理論的な保証の欠如。
コード
\(f(x、y)= x ^ 2 + 50y ^ 2 \)。
{
"dim": 2,
"F": 0.5,
"NP": 5,
"Cr": 0.35
}
"""
de.py
"""
import numpy as np
from scipy import stats
import random
class Parameter:
def __init__(self, dim, xmin, xmax):
self.dim = dim
self.xmin = xmin
self.xmax = xmax
self.initial()
def initial(self):
self.para = stats.uniform.rvs(
self.xmin, self.xmax - self.xmin
)
@property
def data(self):
return self.para
def __getitem__(self, item):
return self.para[item]
def __setitem__(self, key, value):
self.para[key] = value
def __len__(self):
return len(self.para)
def __add__(self, other):
return self.para + other
def __mul__(self, other):
return self.para * other
def __pow__(self, power):
return self.para ** power
def __neg__(self):
return -self.para
def __sub__(self, other):
return self.para - other
def __truediv__(self, other):
return self.para / other
class DE:
def __init__(self, func, dim ,F=0.5, NP=50,
Cr=0.35, xmin=-10, xmax=10,
require_history=True):
self.func = func
self.dim = dim
self.F = F
self.NP = NP
self.Cr = Cr
self.xmin = np.array(xmin)
self.xmax = np.array(xmax)
assert all(self.xmin <= self.xmax), "Invalid xmin or xmax"
self.require_history = require_history
self.init_x()
if self.require_history:
self.build_history()
def init_x(self):
self.paras = [Parameter(self.dim, self.xmin, self.xmax)
for i in range(self.NP)]
@property
def data(self):
return [para.data for para in self.paras]
def build_history(self):
self.paras_history = [self.data]
def add_history(self):
self.paras_history.append(self.data)
def choose(self, size=3):
return random.sample(self.paras, k=size)
def mutation(self):
x1, x2, x3 = self.choose(3)
return x1 + self.F * (x2 - x3)
def crossover(self, v, x):
u = np.zeros_like(v)
for i, _ in enumerate(v):
jrand = random.randint(0, self.dim)
if np.random.rand() < self.Cr or i is jrand:
u[i] = v[i]
else:
u[i] = x[i]
u[i] = v[i] if np.random.rand() < self.Cr else x[i]
return u
def selection(self, u, x):
if self.func(u) < self.func(x):
x.para = u
else:
pass
def step(self):
donors = [self.mutation()
for i in range(self.NP)]
for i, donor in enumerate(donors):
x = self.paras[i]
u = self.crossover(donor, x)
self.selection(u, x)
if self.require_history:
self.add_history()
def multi_steps(self, times):
for i in range(times):
self.step()
class DEbest1(DE):
def bestone(self):
y = np.array([self.func(para)
for para in self.paras])
return self.paras[np.argmax(y)]
def mutation(self, bestone):
x1, x2 = self.choose(2)
return bestone + self.F * (x1 - x2)
def step(self):
bestone = self.bestone()
donors = [self.mutation(bestone)
for i in range(self.NP)]
for i, donor in enumerate(donors):
x = self.paras[i]
u = self.crossover(donor, x)
self.selection(u, x)
if self.require_history:
self.add_history()
class DEbest2(DEbest1):
def mutation(self, bestone):
x1, x2, x3, x4 = self.choose(4)
return bestone + self.F * (x1 - x2) \
+ self.F * (x3 - x4)
class DErand2(DE):
def mutation(self):
x1, x2, x3, x4, x5 = self.choose(5)
return x1 + self.F * (x2 - x3) \
+ self.F * (x4 - x5)
class DErandTM(DE):
def mutation(self):
x = self.choose(3)
y = np.array(list(map(self.func, x)))
p = y / y.sum()
part1 = (x[0] + x[1] + x[2]) / 3
part2 = (p[1] - p[0]) * (x[0] - x[1])
part3 = (p[2] - p[1]) * (x[2] - x[1])
part4 = (p[0] - p[2]) * (x[2] - x[0])
return part1 + part2 + part3 + part4