Skip to content

Commit 18c359d

Browse files
committed
Squashed commit from draft/ben:
commit 81140b0 Merge: 383de26 165c95c Author: AlbertZyy <108785827+AlbertZyy@users.noreply.github.com> Date: Wed Jan 28 15:03:37 2026 +0800 Merge pull request #2144 from BenHBLiu/draft/ben [Recfactor] vectorization cost function commit 165c95c Author: BenHBLiu <benlau0603@outlook.com> Date: Wed Jan 28 12:30:27 2026 +0800 refactor(pahtplanning): vectorization cost function commit 589f1d8 Merge: 383de26 197b1ce Author: BenHBLiu <benlau0603@outlook.com> Date: Wed Jan 28 12:27:26 2026 +0800 Merge branch 'develop' into draft/ben commit 383de26 Merge: b861986 a8cc87f Author: Huayi Wei <weihuayi@xtu.edu.cn> Date: Fri Jan 23 20:11:58 2026 +0800 Merge pull request #2127 from BenHBLiu/draft/ben [Refactor] vectorized mtsp bilevel optimization framework commit a8cc87f Author: BenHBLiu <benlau0603@outlook.com> Date: Tue Jan 20 15:06:33 2026 +0800 refactor(pathplanning): vectorized mtsp bilevel optimization framework commit b861986 Merge: 1d9368e 4fd9a37 Author: AlbertZyy <108785827+AlbertZyy@users.noreply.github.com> Date: Sun Jan 18 22:00:22 2026 +0800 Merge pull request #2123 from BenHBLiu/draft/ben [Feat] add SBOA commit 4fd9a37 Merge: 9717b27 1d9368e Author: BenHBLiu <benlau0603@outlook.com> Date: Tue Jan 13 21:06:38 2026 +0800 Merge branch 'draft/ben' of https://github.com/BenHBLiu/fealpy into draft/ben commit 9717b27 Author: BenHBLiu <benlau0603@outlook.com> Date: Tue Jan 13 21:06:10 2026 +0800 feat(opt): add SBOA commit 1d9368e Merge: b3628f3 7a2620d Author: Huayi Wei <weihuayi@xtu.edu.cn> Date: Mon Oct 27 17:23:00 2025 +0800 Merge pull request #1947 from BenHBLiu/draft/ben [Feat] add HCKEO commit 7a2620d Author: BenHBLiu <benlau0603@outlook.com> Date: Mon Oct 27 16:25:40 2025 +0800 feat(opt): add HCKEO
1 parent 58e047f commit 18c359d

File tree

6 files changed

+893
-176
lines changed

6 files changed

+893
-176
lines changed

example/pathplanning/mtsp_example.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from fealpy.backend import backend_manager as bm
22
from fealpy.pathplanning.model import PathPlanningModelManager
3-
from fealpy.opt import QuantumParticleSwarmOpt, SnowAblationOpt
3+
from fealpy.opt import QuantumParticleSwarmOpt
44

55
# TSP
66
pos = bm.random.rand(15, 2) * 100 # 城市坐标
@@ -47,27 +47,21 @@
4747
[1260, 1910],
4848
[360, 1980],
4949
[420, 1930]
50-
])
50+
], dtype=bm.float64)
5151

5252
warehouse_pos = bm.mean(pos, axis=0)[None, :]
5353

5454
up_opt_dict = {
5555
'opt_alg': QuantumParticleSwarmOpt,
5656
'NP': 50,
57-
'MaxIT': 500
58-
}
59-
down_opt_dict = {
60-
'opt_alg': SnowAblationOpt,
61-
'NP': 50,
62-
'MaxIT': 500
57+
'MaxIT': 300
6358
}
6459

6560
options = {
66-
'uav_num': 4,
61+
'uav_num': 6,
6762
'pos': pos,
6863
'warehouse': warehouse_pos,
6964
'up_opt_dict': up_opt_dict,
70-
'down_opt_dict': down_opt_dict,
7165
}
7266

7367
manager = PathPlanningModelManager('travelling_salesman_prob')

fealpy/opt/swarm_based/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .hippopotamus_opt_alg import HippopotamusOptAlg
1212
from .honeybadger_alg import HoneybadgerAlg
1313
from .jellyfish_search_opt import JellyfishSearchOpt
14-
from .kangaroo_escape_opt import KangarooEscapeOpt
14+
from .kangaroo_escape_opt import KangarooEscapeOpt, HybridCrossoverKangarooEscapeOpt
1515
from .marine_predators_alg import (
1616
MarinePredatorsAlg,
1717
GLS_MarinePredatorsAlg,
@@ -22,6 +22,7 @@
2222
from .remora_opt_alg import RemoraOptAlg
2323
from .sand_cat_swarm_opt import SandCatSwarmOpt
2424
from .seagull_opt_alg import SeagullOptAlg
25+
from .secretary_bird_opt import SecretaryBirdOpt
2526
from .sparrow_search_alg import SparrowSearchAlg
2627
from .squirrel_search_alg import SquirrelSearchAlg
2728
from .starfish_opt_alg import StarFishOptAlg

fealpy/opt/swarm_based/kangaroo_escape_opt.py

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from ...backend import backend_manager as bm
22
from ..optimizer_base import Optimizer
3+
from ..opt_function import levy
34

45
class KangarooEscapeOpt(Optimizer):
56
"""
@@ -140,7 +141,7 @@ def strategy3(self):
140141
# Safe zone selection rule based on optimization phase
141142
if self.it < (3 * self.MaxIT // 4):
142143
# Early phase (first 75%): prefer random exploration
143-
x_safe = x_rand
144+
x_safe = bm.copy(x_rand)
144145
else:
145146
# Later phase (last 25%): 75% chance use group-best, 25% chance use global best
146147
mask2 = bm.random.rand(self.N, 1) < 0.75
@@ -209,6 +210,126 @@ def run(self, params={'beta':1, 'energy_threshold':0.5, 'chaotic_val':0.7}):
209210
mask = fit_new < self.fit
210211
self.x, self.fit = bm.where(mask[:, None], x_new, self.x), bm.where(mask, fit_new, self.fit)
211212

213+
# Update global best solution
214+
self.update_gbest(self.x, self.fit)
215+
self.curve[self.it] = self.gbest_f # Record convergence curve
216+
217+
class HybridCrossoverKangarooEscapeOpt(KangarooEscapeOpt):
218+
def __init__(self, options):
219+
super().__init__(options)
220+
self.energy = bm.ones((self.N, 1))
221+
222+
def strategy1(self):
223+
"""
224+
Levy long jump crossover strategy for global exploration.
225+
226+
Simulates kangaroo's long-distance jumping behavior for escaping predators
227+
and exploring new areas of the search space.
228+
229+
Returns:
230+
array: New positions after long jumps
231+
"""
232+
# Levy long jump crossover strategy (global exploration)
233+
L = levy(self.N, 1, 1.5)
234+
long_jump_crossover = 2 * bm.random.randn(self.N, 1) * (self.x[bm.random.randint(0, self.N, (self.N,))] - self.gbest) * self.decoy_drop
235+
k = 2 * bm.random.rand(self.N, 1) * (self.MaxIT - self.it) / self.MaxIT
236+
levy_crossover = k * L * (self.x[bm.random.randint(0, self.N, (self.N,))] - self.x)
237+
jump = long_jump_crossover + levy_crossover # Gaussian-distributed jumps
238+
x_new = self.x + jump
239+
return x_new
240+
241+
def horizontal_vertical_crossover_strategy(self, x, fit):
242+
r1 = bm.random.rand(self.N//2, self.dim)
243+
r2 = bm.random.rand(self.N//2, self.dim)
244+
c1 = -1 + 2 * bm.random.rand(self.N//2, self.dim)
245+
c2 = -1 + 2 * bm.random.rand(self.N//2, self.dim)
246+
x_odd = x[bm.arange(0, self.N, 2)]
247+
x_even = x[bm.arange(1, self.N, 2)]
248+
x_new1 = r1 * x_odd + (1 - r1) * x_even + c1 * (x_odd - x_even)
249+
x_new2 = r2 * x_even + (1 - r2) * x_odd + c2 * (x_even - x_odd)
250+
x_new = bm.zeros((self.N, self.dim))
251+
x_new[bm.arange(0, self.N, 2)] = bm.copy(x_new1)
252+
x_new[bm.arange(1, self.N, 2)] = bm.copy(x_new2)
253+
x_new = bm.clip(x_new, self.lb, self.ub)
254+
fit_new = self.fun(x_new)
255+
mask = fit_new < fit
256+
x, fit = bm.where(mask[:, None], x_new, x), bm.where(mask, fit_new, fit)
257+
q1 = bm.random.randint(0, self.dim, (self.N,))
258+
offset = bm.random.randint(1, self.dim, (self.N,))
259+
q2 = (q1 + offset) % self.dim
260+
r = bm.random.rand(self.N,)
261+
x_new[bm.arange(self.N), q1] = r * x[bm.arange(self.N), q1] + (1 - r) * x[bm.arange(self.N), q2]
262+
x_new = bm.clip(x_new, self.lb, self.ub)
263+
fit_new = self.fun(x_new)
264+
mask = fit_new < fit
265+
x, fit = bm.where(mask[:, None], x_new, x), bm.where(mask, fit_new, fit)
266+
return x, fit
267+
268+
def cal_energy(self):
269+
# Energy update using chaotic logistic map (nonlinear dynamics)
270+
r = bm.random.rand(self.N, 1)
271+
for i in range(self.N):
272+
self.chaotic_val = 4 * self.chaotic_val * (1 - self.chaotic_val) # Logistic map update
273+
self.energy[i] = (1 - r[i] * (self.it / self.MaxIT)) * (0.95 + 0.05 * self.chaotic_val)
274+
275+
def run(self, params={'beta':1, 'energy_threshold':0.5, 'chaotic_val':0.7}):
276+
"""
277+
Execute the kangaroo escape optimization process.
278+
279+
params (dict): Algorithm control parameters with:
280+
- 'beta': Zigzag step size control (default: 1)
281+
- 'energy_threshold': Energy level for strategy switching (default: 0.5)
282+
- 'chaotic_val': Initial chaotic value for energy dynamics (default: 0.7)
283+
284+
The algorithm features energy-based strategy selection using chaotic logistic maps
285+
and three distinct escape behaviors modeled after real kangaroo predator avoidance.
286+
"""
287+
# Initialize parameters
288+
beta = params.get('beta') # Zigzag step size control
289+
energy_threshold = params.get('energy_threshold') # Strategy switching threshold
290+
self.chaotic_val = params.get('chaotic_val') # Initial chaotic value
291+
292+
# Evaluate initial population
293+
self.fit = self.fun(self.x)
294+
gbest_idx = bm.argmin(self.fit)
295+
self.gbest_f = self.fit[gbest_idx]
296+
self.gbest = self.x[gbest_idx]
297+
298+
# Main optimization loop
299+
for self.it in range(self.MaxIT):
300+
# Apply boundary control (if any in parent class)
301+
self.D_pl_pt(self.it)
302+
303+
# Generate decoy drop pattern for current iteration
304+
self.cal_decoy_drop()
305+
306+
# Random selection between strategies
307+
r = bm.random.rand(self.N, 1)
308+
309+
self.cal_energy()
310+
311+
# Select strategy according to probability and energy level
312+
mask1 = r < 0.5 # 50% chance for safe zone strategy
313+
mask2 = self.energy < energy_threshold # Low energy → long jumps
314+
315+
# Update positions using three strategies with priority:
316+
# 1. Safe zone strategy (50% chance)
317+
# 2. Levy long jump crossover strategy (low energy)
318+
# 3. Zigzag strategy (high energy)
319+
x_new = bm.where(mask1, self.strategy3(), bm.where(mask2, self.strategy1(), self.strategy2(beta)))
320+
321+
# Apply boundary constraints
322+
x_new = bm.clip(x_new, self.lb, self.ub)
323+
324+
# Fitness evaluation of new positions
325+
fit_new = self.fun(x_new)
326+
327+
x_new, fit_new = self.horizontal_vertical_crossover_strategy(x_new, fit_new)
328+
329+
# Greedy selection: replace if better fitness
330+
mask = fit_new < self.fit
331+
self.x, self.fit = bm.where(mask[:, None], x_new, self.x), bm.where(mask, fit_new, self.fit)
332+
212333
# Update global best solution
213334
self.update_gbest(self.x, self.fit)
214335
self.curve[self.it] = self.gbest_f # Record convergence curve

0 commit comments

Comments
 (0)