Edit on GitHub

geneticalgorithm2.mutations

 1from typing import Callable, Dict, Union
 2
 3import random
 4import numpy as np
 5
 6
 7from .utils.aliases import TypeAlias
 8from .utils.funcs import fast_min, fast_max
 9
10
11MutationFloatFunc: TypeAlias = Callable[[float, float, float], float]
12MutationIntFunc: TypeAlias = Callable[[int, int, int], int]
13MutationFunc: TypeAlias = Union[MutationIntFunc, MutationFloatFunc]
14"""
15Function (x, left, right) -> value
16
17Which mutates x to value according to bounds (left, right)
18"""
19
20
21class Mutations:
22    """
23    Mutations functions static class
24    
25    Mutation changes the sample randomly providing the evolution component to optimization
26    """
27
28    @staticmethod
29    def mutations_dict() -> Dict[str, MutationFloatFunc]:
30        return {
31            n: getattr(Mutations, n)()
32            for n in (
33                'uniform_by_x',
34                'uniform_by_center',
35                'gauss_by_center',
36                'gauss_by_x',
37            )
38        }
39
40    @staticmethod
41    def mutations_discrete_dict() -> Dict[str, MutationIntFunc]:
42        return {
43            'uniform_discrete': Mutations.uniform_discrete()
44        }
45
46    @staticmethod
47    def uniform_by_x() -> MutationFloatFunc:
48        
49        def func(x: float, left: float, right: float):
50            alp: float = fast_min(x - left, right - x)
51            return random.uniform(x - alp, x + alp)
52        return func
53
54    @staticmethod
55    def uniform_by_center() -> MutationFloatFunc:
56        
57        def func(x: float, left: float, right: float):
58            return random.uniform(left, right)
59        
60        return func
61
62    @staticmethod
63    def gauss_by_x(sd: float = 0.3) -> MutationFloatFunc:
64        """
65        gauss mutation with x as center and sd*length_of_zone as std
66        """
67        def func(x: float, left: float, right: float):
68            std: float = sd * (right - left)
69            return fast_max(
70                left, 
71                fast_min(right, np.random.normal(loc=x, scale=std))
72            )
73        
74        return func
75
76    @staticmethod
77    def gauss_by_center(sd: float = 0.3) -> MutationFloatFunc:
78        """
79        gauss mutation with (left+right)/2 as center and sd*length_of_zone as std
80        """
81        def func(x: float, left: float, right: float):
82            std: float = sd * (right - left)
83            return fast_max(
84                left, 
85                fast_min(right, np.random.normal(loc=(left + right) * 0.5, scale=std))
86            )
87        
88        return func
89
90    @staticmethod
91    def uniform_discrete() -> MutationIntFunc:
92        def func(x: int, left: int, right: int) -> int:
93            return random.randint(left, right)
94        return func
MutationFloatFunc: typing_extensions.TypeAlias = typing.Callable[[float, float, float], float]
MutationIntFunc: typing_extensions.TypeAlias = typing.Callable[[int, int, int], int]
MutationFunc: typing_extensions.TypeAlias = typing.Union[typing.Callable[[int, int, int], int], typing.Callable[[float, float, float], float]]

Function (x, left, right) -> value

Which mutates x to value according to bounds (left, right)

class Mutations:
23class Mutations:
24    """
25    Mutations functions static class
26    
27    Mutation changes the sample randomly providing the evolution component to optimization
28    """
29
30    @staticmethod
31    def mutations_dict() -> Dict[str, MutationFloatFunc]:
32        return {
33            n: getattr(Mutations, n)()
34            for n in (
35                'uniform_by_x',
36                'uniform_by_center',
37                'gauss_by_center',
38                'gauss_by_x',
39            )
40        }
41
42    @staticmethod
43    def mutations_discrete_dict() -> Dict[str, MutationIntFunc]:
44        return {
45            'uniform_discrete': Mutations.uniform_discrete()
46        }
47
48    @staticmethod
49    def uniform_by_x() -> MutationFloatFunc:
50        
51        def func(x: float, left: float, right: float):
52            alp: float = fast_min(x - left, right - x)
53            return random.uniform(x - alp, x + alp)
54        return func
55
56    @staticmethod
57    def uniform_by_center() -> MutationFloatFunc:
58        
59        def func(x: float, left: float, right: float):
60            return random.uniform(left, right)
61        
62        return func
63
64    @staticmethod
65    def gauss_by_x(sd: float = 0.3) -> MutationFloatFunc:
66        """
67        gauss mutation with x as center and sd*length_of_zone as std
68        """
69        def func(x: float, left: float, right: float):
70            std: float = sd * (right - left)
71            return fast_max(
72                left, 
73                fast_min(right, np.random.normal(loc=x, scale=std))
74            )
75        
76        return func
77
78    @staticmethod
79    def gauss_by_center(sd: float = 0.3) -> MutationFloatFunc:
80        """
81        gauss mutation with (left+right)/2 as center and sd*length_of_zone as std
82        """
83        def func(x: float, left: float, right: float):
84            std: float = sd * (right - left)
85            return fast_max(
86                left, 
87                fast_min(right, np.random.normal(loc=(left + right) * 0.5, scale=std))
88            )
89        
90        return func
91
92    @staticmethod
93    def uniform_discrete() -> MutationIntFunc:
94        def func(x: int, left: int, right: int) -> int:
95            return random.randint(left, right)
96        return func

Mutations functions static class

Mutation changes the sample randomly providing the evolution component to optimization

@staticmethod
def mutations_dict() -> Dict[str, Callable[[float, float, float], float]]:
30    @staticmethod
31    def mutations_dict() -> Dict[str, MutationFloatFunc]:
32        return {
33            n: getattr(Mutations, n)()
34            for n in (
35                'uniform_by_x',
36                'uniform_by_center',
37                'gauss_by_center',
38                'gauss_by_x',
39            )
40        }
@staticmethod
def mutations_discrete_dict() -> Dict[str, Callable[[int, int, int], int]]:
42    @staticmethod
43    def mutations_discrete_dict() -> Dict[str, MutationIntFunc]:
44        return {
45            'uniform_discrete': Mutations.uniform_discrete()
46        }
@staticmethod
def uniform_by_x() -> Callable[[float, float, float], float]:
48    @staticmethod
49    def uniform_by_x() -> MutationFloatFunc:
50        
51        def func(x: float, left: float, right: float):
52            alp: float = fast_min(x - left, right - x)
53            return random.uniform(x - alp, x + alp)
54        return func
@staticmethod
def uniform_by_center() -> Callable[[float, float, float], float]:
56    @staticmethod
57    def uniform_by_center() -> MutationFloatFunc:
58        
59        def func(x: float, left: float, right: float):
60            return random.uniform(left, right)
61        
62        return func
@staticmethod
def gauss_by_x(sd: float = 0.3) -> Callable[[float, float, float], float]:
64    @staticmethod
65    def gauss_by_x(sd: float = 0.3) -> MutationFloatFunc:
66        """
67        gauss mutation with x as center and sd*length_of_zone as std
68        """
69        def func(x: float, left: float, right: float):
70            std: float = sd * (right - left)
71            return fast_max(
72                left, 
73                fast_min(right, np.random.normal(loc=x, scale=std))
74            )
75        
76        return func

gauss mutation with x as center and sd*length_of_zone as std

@staticmethod
def gauss_by_center(sd: float = 0.3) -> Callable[[float, float, float], float]:
78    @staticmethod
79    def gauss_by_center(sd: float = 0.3) -> MutationFloatFunc:
80        """
81        gauss mutation with (left+right)/2 as center and sd*length_of_zone as std
82        """
83        def func(x: float, left: float, right: float):
84            std: float = sd * (right - left)
85            return fast_max(
86                left, 
87                fast_min(right, np.random.normal(loc=(left + right) * 0.5, scale=std))
88            )
89        
90        return func

gauss mutation with (left+right)/2 as center and sd*length_of_zone as std

@staticmethod
def uniform_discrete() -> Callable[[int, int, int], int]:
92    @staticmethod
93    def uniform_discrete() -> MutationIntFunc:
94        def func(x: int, left: int, right: int) -> int:
95            return random.randint(left, right)
96        return func