2. GHA mit CMA-ES

This commit is contained in:
2026-01-12 15:18:39 +01:00
parent 6cc7245b0f
commit bded05a231
5 changed files with 302 additions and 32 deletions

View File

@@ -1,5 +1,5 @@
import numpy as np
from typing import Callable
def felli(x):
N = x.shape[0]
@@ -9,15 +9,16 @@ def felli(x):
return float(np.sum((1e6 ** exponents) * (x ** 2)))
def escma():
def escma(fitnessfct: Callable, N, xmean, sigma, stopfitness, stopeval,
bestEver = np.inf, noImproveGen = 0, absTolImprove = 1e-10, maxNoImproveGen = 100, sigmaImprove = 1e-12):
#Initialization
# User defined input parameters
N = 10
xmean = np.random.rand(N)
sigma = 0.5
stopfitness = 1e-10
stopeval = int(1e3 * N**2)
# N = 10
# xmean = np.random.rand(N)
# sigma = 0.5
# stopfitness = 1e-10
# stopeval = int(1e3 * N**2)
# Strategy parameter setting: Selection
lambda_ = 4 + int(np.floor(3 * np.log(N)))
@@ -52,13 +53,18 @@ def escma():
arz = np.zeros((N, lambda_))
arfitness = np.zeros(lambda_)
gen = 0
print(f' [CMA-ES] Start: lambda = {lambda_}, sigma ={round(sigma, 6)}, stopeval = {stopeval}')
while counteval < stopeval:
gen += 1
# Generate and evaluate lambda offspring
for k in range(lambda_):
arz[:, k] = np.random.randn(N)
arx[:, k] = xmean + sigma * (B @ D @ arz[:, k])
arfitness[k] = felli(arx[:, k])
arfitness[k] = fitnessfct(arx[:, k])
counteval += 1
# Sort by fitness and compute weighted mean into xmean
@@ -70,6 +76,28 @@ def escma():
xmean = arx[:, arindex[:mu]] @ weights
zmean = arz[:, arindex[:mu]] @ weights
# Stagnation check
fbest = arfitness[0]
if bestEver - fbest > absTolImprove:
bestEver = fbest
noImproveGen = 0
else:
noImproveGen = noImproveGen + 1
if gen == 1 or gen%50==0:
print(f' [CMA-ES] Gen {gen}, best = {round(fbest, 6)}, sigma = {sigma:.3g}')
if noImproveGen >= maxNoImproveGen:
print(f' [CMA-ES] Abbruch: keine Verbesserung > {round(absTolImprove, 3)} in {maxNoImproveGen} Generationen.')
break
if sigma < sigmaImprove:
print(f' [CMA-ES] Abbruch: sigma zu klein {sigma:.3g}')
break
# Cumulation: Update evolution paths
ps = (1 - cs) * ps + np.sqrt(cs * (2 - cs) * mueff) * (B @ zmean)
norm_ps = np.linalg.norm(ps)
@@ -103,13 +131,16 @@ def escma():
# Escape flat fitness, or better terminate?
if arfitness[0] == arfitness[int(np.ceil(0.7 * lambda_)) - 1]:
sigma = sigma * np.exp(0.2 + cs / damps)
print("warning: flat fitness, consider reformulating the objective")
print(' [CMA-ES] stopfitness erreicht.')
#print("warning: flat fitness, consider reformulating the objective")
print(f"{counteval}: {arfitness[0]}")
#print(f"{counteval}: {arfitness[0]}")
#Final Message
print(f"{counteval}: {arfitness[0]}")
#print(f"{counteval}: {arfitness[0]}")
xmin = arx[:, arindex[0]]
bestValue = arfitness[0]
print(f' [CMA-ES] Ende: Gen = {gen}, best = {round(bestValue, 6)}')
return xmin