Skip to content

Commit fea9468

Browse files
committed
Merge branch 'dev' into origin/main
2 parents 585afe9 + 48014e0 commit fea9468

File tree

3 files changed

+37
-17
lines changed

3 files changed

+37
-17
lines changed

ruck/_member.py

+29-15
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,21 @@
2121
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2222
# SOFTWARE.
2323
# ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
24+
2425
import re
26+
import warnings
2527
from typing import Generic
2628
from typing import List
2729
from typing import Optional
30+
from typing import Tuple
2831
from typing import TypeVar
29-
30-
import numpy as np
32+
from typing import Union
3133

3234

3335
# ========================================================================= #
3436
# Members #
3537
# ========================================================================= #
38+
import numpy as np
3639

3740

3841
class MemberIsNotEvaluatedError(Exception):
@@ -44,14 +47,15 @@ class MemberAlreadyEvaluatedError(Exception):
4447

4548

4649
T = TypeVar('T')
50+
Fitness = Union[float, Tuple[float, ...]]
4751

4852

4953
_RE_WHITESPACE = re.compile(r'\s\s+')
5054

5155

5256
class Member(Generic[T]):
5357

54-
def __init__(self, value: T, fitness: float = None):
58+
def __init__(self, value: T, fitness: Fitness = None):
5559
self._value = value
5660
self._fitness = None
5761
# set fitness
@@ -63,26 +67,36 @@ def value(self) -> T:
6367
return self._value
6468

6569
@property
66-
def fitness_unsafe(self) -> Optional[float]:
70+
def fitness_unsafe(self) -> Optional[Fitness]:
6771
return self._fitness
6872

73+
@fitness_unsafe.setter
74+
def fitness_unsafe(self, fitness: Fitness):
75+
if self.is_evaluated:
76+
raise MemberAlreadyEvaluatedError('The member has already been evaluated, the fitness can only ever be set once. Create a new member instead!')
77+
if fitness is None:
78+
raise ValueError('cannot set the fitness value to None')
79+
# set the value
80+
self._fitness = fitness
81+
6982
@property
70-
def fitness(self) -> float:
83+
def fitness(self) -> Fitness:
7184
if not self.is_evaluated:
7285
raise MemberIsNotEvaluatedError('The member has not been evaluated, the fitness has not yet been set.')
7386
return self._fitness
7487

7588
@fitness.setter
76-
def fitness(self, fitness: float):
77-
if self.is_evaluated:
78-
raise MemberAlreadyEvaluatedError('The member has already been evaluated, the fitness can only ever be set once. Create a new member instead!')
79-
if np.isnan(fitness):
80-
raise ValueError('fitness values cannot be NaN, this is an error!')
81-
self._fitness = float(fitness)
82-
83-
def set_fitness(self, fitness: float) -> 'Member[T]':
84-
self.fitness = fitness
85-
return self
89+
def fitness(self, fitness: Fitness):
90+
# check values
91+
if isinstance(fitness, (float, int)):
92+
pass
93+
elif isinstance(fitness, tuple):
94+
if not all(isinstance(f, (float, int)) for f in fitness):
95+
warnings.warn('multivariate fitness value does not consist of floats, this is probably an error!')
96+
else:
97+
warnings.warn(f'fitness value is not a float or tuple of floats, this is probably an error! Got type: {type(fitness)}')
98+
# set the value
99+
self.fitness_unsafe = fitness
86100

87101
@property
88102
def is_evaluated(self) -> bool:

ruck/_module.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ class EaModule(Generic[T], HParamsMixin):
5151
def get_stats_groups(self) -> Dict[str, StatsGroup[T, Any]]:
5252
# default stats groups
5353
return {
54-
'fit': StatsGroup(lambda pop: [m.fitness for m in pop], min=np.min, max=np.max, mean=np.mean)
54+
'fit': StatsGroup(
55+
lambda pop: [m.fitness for m in pop],
56+
min =lambda fitnesses: np.min(fitnesses, axis=0).tolist(),
57+
max =lambda fitnesses: np.max(fitnesses, axis=0).tolist(),
58+
mean=lambda fitnesses: np.mean(fitnesses, axis=0, dtype='float64').tolist(),
59+
std =lambda fitnesses: np.std(fitnesses, axis=0, dtype='float64').tolist(),
60+
)
5561
}
5662

5763
def get_progress_stats(self) -> Sequence[str]:

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
author="Nathan Juraj Michlo",
4949
author_email="[email protected]",
5050

51-
version="0.2.0",
51+
version="0.2.1",
5252
python_requires=">=3.6",
5353
packages=setuptools.find_packages(),
5454

0 commit comments

Comments
 (0)