added schaffer2 function

added output for improvement of fitness
added CMAES algorithm, that requires further testing
This commit is contained in:
Daniel Lukats
2019-09-23 14:11:46 +02:00
parent 93e9234ce6
commit 14c7756802
4 changed files with 97 additions and 42 deletions

View File

@@ -10,7 +10,7 @@ class Solver(ABC):
self.function = function
@abstractmethod
def rank(self, samples: Iterable[Iterable[float]], elite_size: int) -> (Iterable[Tuple], Iterable[Tuple], float):
def rank(self, samples: Iterable[Iterable[float]], elite_size: int) -> (Iterable[Iterable[float]], float):
pass
@abstractmethod
@@ -18,7 +18,7 @@ class Solver(ABC):
pass
@abstractmethod
def update(elite: Iterable[Tuple]):
def update(elite: Iterable[Iterable[float]]):
pass
@@ -33,7 +33,7 @@ class SimpleEvolutionStrategy(Solver):
else:
self.sigma = [1] * len(mu)
def rank(self, samples: Iterable[Iterable[float]], elite_size: int) -> (Iterable[Tuple], Iterable[float]):
def rank(self, samples: Iterable[Iterable[float]], elite_size: int) -> (Iterable[Iterable[float]], Iterable[float]):
fitness = self.function.eval(*samples.transpose())
samples = samples[np.argsort(fitness)]
fitness = np.sort(fitness)
@@ -43,6 +43,41 @@ class SimpleEvolutionStrategy(Solver):
def sample(self, n: int) -> Iterable[Iterable[float]]:
return np.array([np.random.multivariate_normal(self.mu, np.diag(self.sigma)) for _ in range(n)])
def update(self, elite: Iterable[Tuple]):
def update(self, elite: Iterable[Iterable[float]]):
self.mu = elite[0]
class CMAEvolutionStrategy(Solver):
def __init__(self, function: Function, mu: Iterable[float], covariances: Iterable[float] = None):
if covariances is not None and len(mu) != covariances.shape[0] and len(mu) != covariances.shape[1]:
raise Exception('Length of mu and covariance matrix must match')
super().__init__(function)
self.mu = mu
if covariances is not None:
self.covariances = covariances
else:
self.covariances = np.array([[1.0, 0.0], [0.0, 1.0]])
def rank(self, samples: Iterable[Iterable[float]], elite_size: int) -> (Iterable[Iterable[float]], Iterable[float]):
fitness = self.function.eval(*samples.transpose())
samples = samples[np.argsort(fitness)]
fitness = np.sort(fitness)
elite = samples[0:elite_size]
return elite, fitness[0]
def sample(self, n: int) -> Iterable[Iterable[float]]:
return np.array([np.random.multivariate_normal(self.mu, self.covariances) for _ in range(n)])
def update(self, elite: Iterable[Iterable[float]]):
mu = self.mu
x = elite.transpose()[0]
y = elite.transpose()[1]
self.mu[0] = np.average(x)
self.mu[1] = np.average(y)
# TODO fix covariance matrix calculation using the tutorial by Nikolaus Hansen
self.covariances[0][0] = np.average((x - mu[0])**2)
self.covariances[1][1] = np.average((y - mu[1])**2)
self.covariances[0][1] = np.average((x - mu[0]) * (y - mu[1]))
# self.covariances = np.cov(elite.transpose())