Hansen Skript roh

This commit is contained in:
Tammo.Weber
2025-12-16 16:25:00 +01:00
parent 936b7c56f9
commit 30a610ccf6

119
Hansen_ES_CMA.py Normal file
View File

@@ -0,0 +1,119 @@
import numpy as np
def felli(x):
N = x.shape[0]
if N < 2:
raise ValueError("dimension must be greater than one")
exponents = np.arange(N) / (N - 1)
return float(np.sum((1e6 ** exponents) * (x ** 2)))
def escma():
#Initialization
# User defined input parameters
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)))
mu = lambda_ / 2.0
# muXone recombination weights
weights = np.log(mu + 0.5) - np.log(np.arange(1, int(mu) + 1))
mu = int(np.floor(mu))
weights = weights / np.sum(weights)
mueff = np.sum(weights)**2 / np.sum(weights**2)
# Strategy parameter setting: Adaptation
cc = (4 + mueff / N) / (N + 4 + 2 * mueff / N)
cs = (mueff + 2) / (N + mueff + 5)
c1 = 2 / ((N + 1.3)**2 + mueff)
cmu = min(1 - c1,
2 * (mueff - 2 + 1 / mueff) / ((N + 2)**2 + 2 * mueff))
damps = 1 + 2 * max(0, np.sqrt((mueff - 1) / (N + 1)) - 1) + cs
# Initialize dynamic (internal) strategy parameters and constants
pc = np.zeros(N)
ps = np.zeros(N)
B = np.eye(N)
D = np.eye(N)
C = B @ D @ (B @ D).T
eigeneval = 0
chiN = np.sqrt(N) * (1 - 1/(4*N) + 1/(21 * N**2))
#Generation Loop
counteval = 0
arx = np.zeros((N, lambda_))
arz = np.zeros((N, lambda_))
arfitness = np.zeros(lambda_)
while counteval < stopeval:
# 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])
counteval += 1
# Sort by fitness and compute weighted mean into xmean
idx = np.argsort(arfitness)
arfitness = arfitness[idx]
arindex = idx
xold = xmean.copy()
xmean = arx[:, arindex[:mu]] @ weights
zmean = arz[:, arindex[:mu]] @ weights
# Cumulation: Update evolution paths
ps = (1 - cs) * ps + np.sqrt(cs * (2 - cs) * mueff) * (B @ zmean)
norm_ps = np.linalg.norm(ps)
hsig = norm_ps / np.sqrt(1 - (1 - cs)**(2 * counteval / lambda_)) / chiN < \
(1.4 + 2 / (N + 1))
hsig = 1.0 if hsig else 0.0
pc = (1 - cc) * pc + hsig * np.sqrt(cc * (2 - cc) * mueff) * (B @ D @ zmean)
# Adapt covariance matrix C
BDz = B @ D @ arz[:, arindex[:mu]]
C = (1 - c1 - cmu) * C \
+ c1 * (np.outer(pc, pc) + (1 - hsig) * cc * (2 - cc) * C) \
+ cmu * BDz @ np.diag(weights) @ BDz.T
# Adapt step-size sigma
sigma = sigma * np.exp((cs / damps) * (norm_ps / chiN - 1))
# Update B and D from C (Eigenzerlegung, O(N^2))
if counteval - eigeneval > lambda_ / ((c1 + cmu) * N * 10):
eigeneval = counteval
# enforce symmetry
C = (C + C.T) / 2.0
eigvals, B = np.linalg.eigh(C)
D = np.diag(np.sqrt(eigvals))
# Break, if fitness is good enough
if arfitness[0] <= stopfitness:
break
# 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(f"{counteval}: {arfitness[0]}")
#Final Message
print(f"{counteval}: {arfitness[0]}")
xmin = arx[:, arindex[0]]
return xmin
if __name__ == "__main__":
xmin = escma()
print("Bestes gefundenes x:", xmin)
print("f(xmin) =", felli(xmin))