Completed
Push — master ( 941fee...e45971 )
by Andrei
57s
created

ga_math.set_last_value_to_one()   A

Complexity

Conditions 3

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
1
"""!
2
3
@brief Genetic algorithm math API.
4
5
@authors Aleksey Kukushkin ([email protected])
6
@date 2014-2017
7
@copyright GNU Public License
8
9
@cond GNU_PUBLIC_LICENSE
10
    PyClustering is free software: you can redistribute it and/or modify
11
    it under the terms of the GNU General Public License as published by
12
    the Free Software Foundation, either version 3 of the License, or
13
    (at your option) any later version.
14
    
15
    PyClustering is distributed in the hope that it will be useful,
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
    GNU General Public License for more details.
19
    
20
    You should have received a copy of the GNU General Public License
21
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
@endcond
23
24
"""
25
26
27
import numpy as np;
0 ignored issues
show
Configuration introduced by
The import numpy could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
28
29
30
class ga_math:
31
    """
32
    @brief Genetic algorithm math API.
33
    
34
    """
35
36
    @staticmethod
37
    def calc_count_centers(chromosome):
38
        return chromosome[chromosome.argmax()] + 1
39
40
    @staticmethod
41
    def get_clusters_representation(chromosome, count_clusters=None):
42
        """ Convert chromosome to cluster representation:
43
                chromosome : [0, 1, 1, 0, 2, 3, 3]
44
                clusters: [[0, 3], [1, 2], [4], [5, 6]]
45
        """
46
47
        if count_clusters is None:
48
            count_clusters = ga_math.calc_count_centers(chromosome)
49
50
        # Initialize empty clusters
51
        clusters = [[] for _ in range(count_clusters)]
52
53
        # Fill clusters with index of data
54
        for _idx_data in range(len(chromosome)):
55
            clusters[chromosome[_idx_data]].append(_idx_data)
56
57
        return clusters
58
59
    @staticmethod
60
    def get_centres(chromosomes, data, count_clusters):
61
        """!
62
        """
63
64
        centres = ga_math.calc_centers(chromosomes, data, count_clusters)
65
66
        return centres
67
68
    @staticmethod
69
    def calc_centers(chromosomes, data, count_clusters=None):
70
        """!
71
        """
72
73
        if count_clusters is None:
74
            count_clusters = ga_math.calc_count_centers(chromosomes[0])
75
76
        # Initialize center
77
        centers = np.zeros(shape=(len(chromosomes), count_clusters, len(data[0])))
78
79
        for _idx_chromosome in range(len(chromosomes)):
80
81
            # Get count data in clusters
82
            count_data_in_cluster = np.zeros(count_clusters)
83
84
            # Next data point
85
            for _idx in range(len(chromosomes[_idx_chromosome])):
86
87
                cluster_num = chromosomes[_idx_chromosome][_idx]
88
89
                centers[_idx_chromosome][cluster_num] += data[_idx]
90
                count_data_in_cluster[cluster_num] += 1
91
92
            for _idx_cluster in range(count_clusters):
93
                if count_data_in_cluster[_idx_cluster] != 0:
94
                    centers[_idx_chromosome][_idx_cluster] /= count_data_in_cluster[_idx_cluster]
95
96
        return centers
97
98
    @staticmethod
99
    def calc_probability_vector(fitness):
100
        """!
101
        """
102
103
        if len(fitness) == 0:
104
            raise AttributeError("Has no any fitness functions.")
105
106
        # Get 1/fitness function
107
        inv_fitness = np.zeros(len(fitness))
108
109
        #
110
        for _idx in range(len(inv_fitness)):
111
112
            if fitness[_idx] != 0.0:
113
                inv_fitness[_idx] = 1.0 / fitness[_idx]
114
            else:
115
                inv_fitness[_idx] = 0.0
116
117
        # Initialize vector
118
        prob = np.zeros(len(fitness))
119
120
        # Initialize first element
121
        prob[0] = inv_fitness[0]
122
123
        # Accumulate values in probability vector
124
        for _idx in range(1, len(inv_fitness)):
125
            prob[_idx] = prob[_idx - 1] + inv_fitness[_idx]
126
127
        # Normalize
128
        prob /= prob[-1]
129
130
        ga_math.set_last_value_to_one(prob)
131
132
        return prob
133
134
    @staticmethod
135
    def set_last_value_to_one(probabilities):
136
        """!
137
        @brief Update the last same probabilities to one.
138
        @details All values of probability list equals to the last element are set to 1.
139
        
140
        """
141
142
        # Start from the last elem
143
        back_idx = - 1
144
145
        # All values equal to the last elem should be set to 1
146
        last_val = probabilities[back_idx]
147
148
        # for all elements or if a elem not equal to the last elem
149
        for _ in range(-1, -len(probabilities) - 1):
150
            if probabilities[back_idx] == last_val:
151
                probabilities[back_idx] = 1
152
            else:
153
                break
154
155
    @staticmethod
156
    def get_uniform(probabilities):
157
        """!
158
        @brief Returns index in probabilities.
159
160
        @param[in] probabilities (list): List with segments in increasing sequence with val in [0, 1],
161
                   for example, [0 0.1 0.2 0.3 1.0].
162
        """
163
164
        # Initialize return value
165
        res_idx = None
166
167
        # Get random num in range [0, 1)
168
        random_num = np.random.rand()
169
170
        # Find segment with  val1 < random_num < val2
171
        for _idx in range(len(probabilities)):
172
            if random_num < probabilities[_idx]:
173
                res_idx = _idx
174
                break
175
176
        if res_idx is None:
177
            print('Probabilities : ', probabilities)
178
            raise AttributeError("'probabilities' should contain 1 as the end of last segment(s)")
179
180
        return res_idx
181
182