source: framspy/evolalg/dissimilarity/frams_dissimilarity.py @ 1145

Last change on this file since 1145 was 1145, checked in by Maciej Komosinski, 3 years ago

Added niching and novelty search with limited (i.e., local) competition ("nearest neighbors" according to dissimilarity measure)

File size: 1.7 KB
Line 
1from abc import ABC
2
3import numpy as np
4
5from evolalg.base.frams_step import FramsStep
6from evolalg.dissimilarity.dissimilarity import Dissimilarity
7
8#TODO eliminate overlap with dissimilarity.py
9
10
11class FramsDissimilarity(FramsStep):
12
13    def __init__(self, frams_lib, reduction="mean", output_field="dissim", knn=None, *args, **kwargs):
14        super(FramsDissimilarity, self).__init__(frams_lib, *args, **kwargs)
15
16        self.output_field = output_field
17        self.fn_reduce = None
18        self.knn = knn
19        if reduction == "mean":
20            self.fn_reduce = np.mean
21        elif reduction == "max":
22            self.fn_reduce = np.max
23        elif reduction == "min":
24            self.fn_reduce = np.min
25        elif reduction == "sum":
26            self.fn_reduce = np.sum
27        elif reduction == "knn_mean":
28            self.fn_reduce = self.knn_mean
29        elif reduction == "none" or reduction is None:
30            self.fn_reduce = None
31        else:
32            raise ValueError("Unknown reduction type. Supported: mean, max, min, sum, knn_mean, none")
33
34    def reduce(self, dissim_matrix):
35        if self.fn_reduce is None:
36            return dissim_matrix
37        return self.fn_reduce(dissim_matrix, axis=1)
38
39    def call(self, population):
40        super(FramsDissimilarity, self).call(population)
41        if len(population) == 0:
42            return []
43        dissim_matrix = self.frams.dissimilarity([_.genotype for _ in population])
44        dissim = self.reduce(dissim_matrix)
45        for d,ind in zip(dissim, population):
46            setattr(ind, self.output_field, d)
47        return population
48
49    def knn_mean(self, dissim_matrix,axis):
50        return np.mean(np.partition(dissim_matrix, self.knn)[:,:self.knn],axis=axis)
Note: See TracBrowser for help on using the repository browser.