2. GHA mit CMA-ES
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user