この記事について
メタファー系の3つめ、Moth-Flame Optimization(MFO:日本語だと蛾最適化と呼ぶらしい、かっこいいですね) です。蛾が月明かりを頼りに飛ぶ性質(横光定位)と、人工の光源に対してらせんを描いて近づいてしまう現象を模した手法です。
GWO(⑥)・HHO(⑦)と同じ作者グループ(Mirjalili 系)の手法で、骨格は共通ですが「炎へ向かう動きをらせんで表現する」のが特徴です。
メタヒューリスティクス図鑑シリーズの記事一覧はこちら。
| 記事 | 内容 |
|---|---|
| ⓪〜⑤ | 入門・地図/PSO・ACO・CMA-ES・GA・Cuckoo |
| ⑥⑦ | Grey Wolf Optimizer/Harris Hawks Optimization |
| ⑧(本記事) | Moth-Flame Optimization(MFO) |
| ⑨ | Grasshopper Optimization(GOA) |
| ⑩ | Golden Jackal Optimization(GJO) |
| ⑪ | Manta Ray Foraging(MRFO) |
| ⑫ | まとめ:メタファー系の正体と使い分け |
MFOとは
2015年に Seyedali Mirjalili が提案しました。
S. Mirjalili, "Moth-Flame Optimization Algorithm: A novel nature-inspired heuristic paradigm,"
Knowledge-Based Systems, vol. 89, pp. 228-249, 2015.
登場するのは「蛾(moth)」と「炎(flame)」です。蛾が探索エージェント、炎がこれまでに見つかった良い位置(リーダー)にあたります。各蛾は対応する炎の周りを対数らせんで飛び、だんだん炎に近づいていきます。
核心:対数らせんで炎へ近づく
蛾 $M_i$ は炎 $F_j$ に対して、次のらせん運動で更新されます。
M_i = \underbrace{D_{ij}\cdot e^{bt}\cos(2\pi t)}_{\text{らせんの回り込み}} + \underbrace{F_j}_{\text{炎の位置}},
\qquad D_{ij} = |F_j - M_i|
| 記号 | 意味 |
|---|---|
| $D_{ij}$ | 蛾と炎の距離 |
| $b$ | らせんの形を決める定数 |
| $t$ | $[-1, 1]$ の乱数($-1$ で炎に最接近、$1$ で最も遠い) |
$\cos(2\pi t)$ で炎の周りを回り込みながら、$e^{bt}$ で距離を調整して近づく ── これが「光源に巻き込まれる蛾」のイメージです。
炎の数を減らしていく工夫
MFO の肝は、炎の数を反復とともに減らすことです。
\text{flame\_no} = \mathrm{round}\!\left(N - t\cdot\frac{N-1}{T}\right)
最初は炎がたくさんあり(多様な方向へ探索)、終盤は炎が1つに絞られます(最良解へ収束)。これが⓪の「探索→活用」を実現する仕掛けで、GWO の係数 $a$、HHO のエネルギー $E$ に対応する役割です。
図で見る
- ①(左)対数らせん:$t$ を $-1$ から $+1$ まで動かしたときの軌跡です。$\cos(2\pi t)$ が炎のまわりを回り込ませ、$e^{bt}$ が距離を決める。$t=-1$ で炎に最接近し、$t=+1$ で最も遠くなります。「光源に巻き込まれる蛾」のイメージそのものですね
-
②(中)実際の着地点:実装をよく見てもらうとわかる通り、$t$ は次元ごとに独立に引かれます(
for k in range(dim)の中でrng.random())。なので2次元での実際の着地点は、①のようなきれいな曲線ではなく炎を中心に格子状に散らばります。らせんは「1次元ずつ見たときの動き」であって、多次元での軌跡ではない、というのは知っておくと混乱しません - ③(右)炎の数:$N=30$ から $1$ まで階段状に減っていきます。序盤は30個の炎に散らばって探索し、終盤は1個の炎(=最良解)へ全員が収束します
つまりMFOは、「らせんという動き方」と「炎の数を減らすスケジュール」の2段構えで探索と活用を切り替えているわけです。
Python実装
import numpy as np
from math import pi
def mfo(func, dim, lb, ub, n_agents=30, n_iter=500, seed=0, b=1.0):
rng = np.random.default_rng(seed)
X = rng.uniform(lb, ub, (n_agents, dim))
best_flames = best_fit = None
history = []
for t in range(n_iter):
fit = np.array([func(x) for x in X])
if best_flames is None: # 炎=これまでの良い位置
order = np.argsort(fit)
best_flames, best_fit = X[order].copy(), fit[order].copy()
else: # 過去の炎と統合してソート
comb = np.vstack([best_flames, X])
cfit = np.concatenate([best_fit, fit])
order = np.argsort(cfit)[:n_agents]
best_flames, best_fit = comb[order].copy(), cfit[order].copy()
flame_no = round(n_agents - t * (n_agents - 1) / n_iter) # 炎を減らす
a = -1 - t / n_iter # らせん係数 -1→-2
for i in range(n_agents):
for k in range(dim):
j = i if i < flame_no else flame_no - 1
dist = abs(best_flames[j, k] - X[i, k])
tt = (a - 1) * rng.random() + 1
X[i, k] = dist * np.exp(b * tt) * np.cos(2 * pi * tt) + best_flames[j, k]
X = np.clip(X, lb, ub)
history.append(best_fit[0])
return best_flames[0], best_fit[0], history
Rastrigin(2次元)で実行します。
_, best_f, history = mfo(rastrigin, dim=2, lb=-5.12, ub=5.12, seed=0)
print(f'MFO 最良値 f = {best_f:.6e} (初期 {history[0]:.3f} → 最終 {history[-1]:.3e})')
MFO 最良値 f = 0.000000e+00 (初期 9.480 → 最終 0.000e+00)
2次元では大域最適に到達しました。
ただし次元が上がると苦戦します。10次元・10シード平均では Rastrigin で $22.0 \pm 10.0$、Ackley で $0.12 \pm 0.35$ と、今回のメタファー系の中では低調でした。らせんによる収束は2〜数次元では効きますが、高次元の多峰性では炎の数を減らす戦略だけでは多様性を保ちきれない、という印象です。
同じ作者・同じ骨格
MFO は GWO・HHO と同じ Mirjalili 系の手法で、骨格はやはり共通です。
| 手法 | リーダー | 探索→活用のつまみ | 動きのメタファー |
|---|---|---|---|
| GWO(⑥) | 上位3頭 $\alpha/\beta/\delta$ | 係数 $a$($2\to0$) | 獲物を囲い込む |
| HHO(⑦) | ウサギ(最良1点) | エネルギー $E$ | 包囲+急降下 |
| MFO(本記事) | 炎(複数→1つ) | 炎の数($N\to1$) | らせんで近づく |
「リーダーへ係数つきで近づき、そのつまみを反復で絞る」という構造は全く同じで、違いは『つまみの名前』と『近づき方の式』だけです。⑫でこの点を総括します。
まとめ
- MFO は蛾が炎(光源)へ対数らせんで巻き込まれる現象を模した手法
- 炎=これまでの良い位置(リーダー)、蛾=探索エージェント
- 炎の数を $N\to1$ へ減らすことで探索→活用を実現する(GWOの $a$・HHOの $E$ と同役割)
- 低次元では大域最適に届くが、高次元の多峰性では低調(Rastrigin 10次元で $22.0$)
- GWO・HHO と同じ骨格で、違いは「つまみと近づき方」だけ
次回はGrasshopper Optimization Algorithm(GOA)、バッタの群れの引力と斥力を使う手法です。
参考にした記事や本、論文等
- S. Mirjalili, "Moth-Flame Optimization Algorithm: A novel nature-inspired heuristic paradigm," Knowledge-Based Systems, vol. 89, pp. 228-249, 2015.

