0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【メタヒューリスティクス図鑑】Harris Hawks Optimization(HHO)─タカの包囲と急降下⑦

0
Posted at

この記事について

前回(⑥)の Grey Wolf Optimizer に続き、メタファー系の中でも特に強力な Harris Hawks Optimization(HHO:ハリスホーク最適化) です。

GWO が「係数1つで探索と活用を切り替える」シンプルさだったのに対し、HHO は獲物の「脱出エネルギー」に応じて4つの攻撃戦略を使い分ける、やや凝った作りになっています。

メタヒューリスティクス図鑑シリーズの記事一覧はこちら。

記事 内容
⓪〜⑤ 入門・地図/PSO・ACO・CMA-ES・GA・Cuckoo
Grey Wolf Optimizer(GWO)
⑦(本記事) Harris Hawks Optimization(HHO)
Moth-Flame Optimization(MFO)
Grasshopper Optimization(GOA)
Golden Jackal Optimization(GJO)
Manta Ray Foraging(MRFO)
まとめ:メタファー系の正体と使い分け

HHOとは

2019年に Heidari らが提案しました。提案から数年で引用数が数千に達した人気手法です。

A. A. Heidari et al., "Harris hawks optimization: Algorithm and applications,"
Future Generation Computer Systems, vol. 97, pp. 849-872, 2019.

ハリスホーク(タカの一種)の協調的な狩りを模します。複数のタカがウサギ(最適解)を取り囲み、獲物の体力に応じて「ゆっくり包囲」「一気に襲撃」「フェイントを入れた急降下」などを使い分ける、というストーリーです。

核心:脱出エネルギーで戦略を切り替える

HHO の心臓部は、獲物の脱出エネルギー $E$ です。

E = 2E_0\left(1 - \frac{t}{T}\right),\qquad E_0 \sim U[-1, 1]

$E$ の絶対値が反復とともに小さくなり、これで探索フェーズと活用フェーズを切り替えます。⑥でみた「係数で探索↔活用」の骨格と同じで、$E$ がそのつまみです。

条件 フェーズ 行動
$\vert E\vert \ge 1$ 探索 ランダムなタカや群れの中心を基準に広く探す
$\vert E\vert < 1$ 活用 ウサギを囲い込む(下の4戦略)

活用フェーズでは、獲物に逃げ切られるかどうかを決める乱数 $r$ とエネルギー $\vert E\vert$ で4つに分岐します($r<0.5$ が「逃げ切られそう」の側です)。

$r$ $\vert E\vert$ 戦略
$\ge 0.5$ $\ge 0.5$ ソフト包囲(ゆっくり囲う)
$\ge 0.5$ $< 0.5$ ハード包囲(一気に詰める)
$< 0.5$ $\ge 0.5$ 急降下つきソフト包囲(Lévyでフェイント)
$< 0.5$ $< 0.5$ 急降下つきハード包囲(Lévyでフェイント)

急降下戦略では⑤で導入したLévyフライトが使われます。要するに「獲物との距離をエネルギーで重みづけて詰める+たまにLévyで大きく動く」を、状況で細かく出し分けているわけです。

図で見る

言葉だけだと分岐が多くて迷子になるので、図にまとめました。②と③は同じ2×2の配置・同じ色にしてあります。上下が「詰め方の速さ」(オレンジ=ゆっくり/赤=一気に)、**左右が「Lévyのフェイントの有無」**です。

20260801_hho_strategy.png

  • ①(左):脱出エネルギー $\vert E\vert$ の推移。太い線が上限 $2(1-t/T)$ で、細い灰色の線が個体ごとの $\vert E\vert$ です。$E_0$ が $[-1,1]$ の乱数なので同じ反復でも個体ごとにバラつくのがポイントで、序盤でも「もう囲い込みに入る個体」がいます。反復が進むほど、青い帯(探索)→オレンジの帯(ソフト包囲)→赤い帯(ハード包囲)と下へ落ちていきます
  • ②(中):活用フェーズの4分岐。縦軸が「獲物の体力」$\vert E\vert$、横軸が「逃げ切られそうかどうか」$r$ と読むと素直です。上半分(体力あり)はゆっくり、下半分(弱っている)は一気に。左半分(逃げられそう)にだけ、Lévyのフェイント(ギザギザの印)が入ります
  • ③(右):その4戦略でタカの動きがどう変わるか(★がウサギ、●がタカの出発点、点線の円はウサギからの距離の目安)。②と同じマスの位置・同じ色なので、そのまま見比べられます
    • 右上・ソフト包囲:小刻みに回り込みながら、16手かけてじわじわ距離を詰める
    • 右下・ハード包囲:大股3手で一直線に詰め切る
    • 左列・急降下つき:同じ動きに Lévyの大ジャンプ(破線) が混ざり、いったん大きく外へ飛んでから詰め直す

体力が残っている獲物には回り込んでじわじわ、弱った獲物には一気に。逃げられそうなときはフェイントを混ぜる」——狩りの比喩としてはよくできているなと思います。

Python実装

分岐が多いので少し長いですが、上の表に対応しています。

import numpy as np
# levy() は ⑤で定義したもの

def hho(func, dim, lb, ub, n_agents=30, n_iter=500, seed=0):
    rng = np.random.default_rng(seed)
    X = rng.uniform(lb, ub, (n_agents, dim))
    fit = np.array([func(x) for x in X])
    rabbit = X[np.argmin(fit)].copy(); frab = fit.min()
    history = []
    for t in range(n_iter):
        E1 = 2 * (1 - t / n_iter)
        for i in range(n_agents):
            E = E1 * (2 * rng.random() - 1)          # 脱出エネルギー
            if abs(E) >= 1:                           # --- 探索 ---
                if rng.random() >= 0.5:
                    rand = X[rng.integers(n_agents)]
                    new = rand - rng.random() * np.abs(rand - 2 * rng.random() * X[i])
                else:
                    new = (rabbit - X.mean(0)) - rng.random() * (lb + rng.random() * (ub - lb))
            else:                                     # --- 活用(4戦略)---
                r = rng.random(); J = 2 * (1 - rng.random())
                if r >= 0.5 and abs(E) >= 0.5:        # ソフト包囲
                    new = (rabbit - X[i]) - E * np.abs(J * rabbit - X[i])
                elif r >= 0.5:                        # ハード包囲
                    new = rabbit - E * np.abs(rabbit - X[i])
                elif abs(E) >= 0.5:                   # 急降下つきソフト包囲
                    Y = rabbit - E * np.abs(J * rabbit - X[i])
                    Z = Y + rng.random(dim) * levy(dim, rng)
                    new = Y if func(np.clip(Y, lb, ub)) < func(np.clip(Z, lb, ub)) else Z
                else:                                 # 急降下つきハード包囲
                    Y = rabbit - E * np.abs(J * rabbit - X.mean(0))
                    Z = Y + rng.random(dim) * levy(dim, rng)
                    new = Y if func(np.clip(Y, lb, ub)) < func(np.clip(Z, lb, ub)) else Z
            X[i] = np.clip(new, lb, ub)
            f = func(X[i])
            if f < frab:
                frab, rabbit = f, X[i].copy()
        history.append(frab)
    return rabbit, frab, history

Rastrigin(2次元)で実行します。

_, best_f, history = hho(rastrigin, dim=2, lb=-5.12, ub=5.12, seed=0)
print(f'HHO 最良値 f = {best_f:.6e}  (初期 {history[0]:.3f} → 最終 {history[-1]:.3e}')
HHO 最良値 f = 0.000000e+00  (初期 2.904 → 最終 0.000e+00)

こちらも厳密に $f=0$。収束曲線でも滑らかに底まで落ちています。

20260801_hho_convergence.png

10次元・10シード平均では Rastrigin で $0.0$(全シードで大域最適)、Ackley で $4.4\times10^{-16}$ と、今回のラインナップで最強クラスでした。

HHO の強さの一部も「原点バイアス」由来

HHO の成績は本物に見えますが、⑥の GWO 同様、最適解が原点にあるベンチマークで有利な面があります。更新式の「$\text{rabbit} - E\cdot|\dots|$」や「群れ平均との差」は、やはり中心方向への引力を生みがちです。

⑫で最適解を原点からずらすと、HHO は $0.0 \to 5.6\times10^{-3}$ と悪化します。GWO・GJO・MRFO ほど壊滅的ではないものの、「原点だと出来すぎ」だったことは確かです。ベンチマークの選び方ひとつで順位が変わる、という点は頭に入れておきたいところです。

まとめ

  • HHO はハリスホークの協調狩りを模し、脱出エネルギー $E$ で探索・活用と4つの攻撃戦略を切り替える
  • 急降下戦略には⑤のLévyフライトが使われる
  • 原点最適のベンチマークでは最強クラス(Rastrigin 10次元で全シード $f=0$)
  • ただし強さの一部は原点バイアス由来で、最適解をずらすと悪化する(⑫で検証)
  • 骨格はやはり「リーダー(ウサギ)へ係数つきで詰める」── GWO と同じ型に4分岐を足したもの

次回はMoth-Flame Optimization(MFO)、蛾が炎へらせんを描く手法です。

参考にした記事や本、論文等

  • A. A. Heidari, S. Mirjalili, H. Faris, I. Aljarah, M. Mafarja, and H. Chen, "Harris hawks optimization: Algorithm and applications," Future Generation Computer Systems, vol. 97, pp. 849-872, 2019.
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?