Passed
Pull Request — master (#98)
by
unknown
01:06
created

GeneticAlgorithm.tryEval()   A

Complexity

Conditions 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 2
c 1
b 1
f 0
dl 0
loc 6
rs 9.4285
1
import random as rnd
2
import copy
3
from NiaPy.benchmarks.utility import Utility
4
5
__all__ = ['GeneticAlgorithm']
6
7
8 View Code Duplication
class Chromosome(object):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
9
    # pylint: disable=too-many-instance-attributes
10
    def __init__(self, D, LB, UB):
11
        self.D = D
12
        self.LB = LB
13
        self.UB = UB
14
15
        self.Solution = []
16
        self.Fitness = float('inf')
17
        self.generateSolution()
18
19
    def generateSolution(self):
20
        self.Solution = [self.LB + (self.UB - self.LB) * rnd.random()
21
                         for _i in range(self.D)]
22
23
    def evaluate(self):
24
        self.Fitness = Chromosome.FuncEval(self.D, self.Solution)
25
26
    def repair(self):
27
        for i in range(self.D):
28
            if self.Solution[i] > self.UB:
29
                self.Solution[i] = self.UB
30
            if self.Solution[i] < self.LB:
31
                self.Solution[i] = self.LB
32
33
    def __eq__(self, other):
34
        return self.Solution == other.Solution and self.Fitness == other.Fitness
35
36
    def toString(self):
37
        print([i for i in self.Solution])
38
39
40
class GeneticAlgorithm(object):
41
    r"""Implementation of Genetic algorithm.
42
43
    **Algorithm:** Genetic algorithm
44
45
    **Date:** 2018
46
47
    **Author:** Uros Mlakar
48
49
    **License:** MIT
50
51
    **Reference paper:** TODO.
52
53
    TODO:  - BUG is somewhere in code
54
    """
55
56
    def __init__(self, D, NP, nFES, Ts, Mr,gamma, benchmark):
57
        self.benchmark = Utility().get_benchmark(benchmark)
58
        self.NP = NP
59
        self.D = D
60
        self.Ts = Ts
61
        self.Mr = Mr
62
	self.gamma = gamma
0 ignored issues
show
introduced by
inconsistent use of tabs and spaces in indentation (<string>, line 62)
Loading history...
63
        self.Lower = self.benchmark.Lower
64
        self.Upper = self.benchmark.Upper
65
        self.Population = []
66
        self.nFES = nFES
67
	self.FEs = 0
68
	self.Done = False
69
        Chromosome.FuncEval = staticmethod(self.benchmark.function())
70
71
        self.Best = Chromosome(self.D, self.Lower, self.Upper)
72
73
    def checkForBest(self, pChromosome):
74
        if pChromosome.Fitness <= self.Best.Fitness:
75
            self.Best = copy.deepcopy(pChromosome)
76
77
    def TournamentSelection(self):
78
        indices = range(self.NP)
79
        rnd.shuffle(indices)
80
        tPop = []
81
        for i in range(self.Ts):
82
            tPop.append(self.Population[i])
83
        tPop.sort(key=lambda x: x.Fitness)
84
85
        self.Population.remove(tPop[0])
86
        self.Population.remove(tPop[1])
87
        return tPop[0], tPop[1]
88
89
    def CrossOver(self, parent1, parent2):
90
        alpha = [-self.gamma + (1 + 2 * self.gamma) * rnd.random()
91
                 for i in range(self.D)]
92
        child1 = Chromosome(self.D, self.Lower, self.Upper)
93
        child2 = Chromosome(self.D, self.Lower, self.Upper)
94
        child1.Solution = [alpha[i] * parent1.Solution[i] +
95
                           (1 - alpha[i]) * parent2.Solution[i] for i in range(self.D)]
96
        child2.Solution = [alpha[i] * parent2.Solution[i] +
97
                           (1 - alpha[i]) * parent1.Solution[i] for i in range(self.D)]
98
        return child1, child2
99
100
    def Mutate(self, child):
101
        for i in range(self.D):
102
            if rnd.random() < self.Mr:
103
                sigma = 0.20 * float(child.UB - child.LB)
104
                child.Solution[i] = min(
105
                    max(rnd.gauss(child.Solution[i], sigma), child.LB), child.UB)
106
107
    def init(self):
108
        for i in range(self.NP):
109
            self.Population.append(Chromosome(self.D, self.Lower, self.Upper))
110
            self.Population[i].evaluate()
111
            self.checkForBest(self.Population[i])
112
113
    def tryEval(self,c):
114
	if self.FEs < self.nFES:
115
	    self.FEs += 1
116
	    c.evaluate()
117
	else:
118
	    self.Done = True
119
120
    def run(self):
121
        self.init()
122
        self.FEs = self.NP
123
        while not self.Done:
124
            for _k in range(self.NP / 2):
125
                parent1, parent2 = self.TournamentSelection()
126
                child1, child2 = self.CrossOver(parent1, parent2)
127
128
                self.Mutate(child1)
129
                self.Mutate(child2)
130
131
                child1.repair()
132
                child2.repair()
133
134
                self.tryEval(child1)
135
                self.tryEval(child2)
136
                
137
138
                tPop = [parent1, parent2, child1, child2]
139
                tPop.sort(key=lambda x: x.Fitness)
140
                self.Population.append(tPop[0])
141
                self.Population.append(tPop[1])
142
143
            for i in range(self.NP):
144
                self.checkForBest(self.Population[i])
145
        return self.Best.Fitness
146