Passed
Pull Request — master (#75)
by Grega
02:24
created

SelfAdaptiveDifferentialEvolutionAlgorithm   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 90
Duplicated Lines 35.56 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 32
loc 90
rs 10
c 1
b 0
f 0
wmc 20

6 Methods

Rating   Name   Duplication   Size   Complexity  
F generationStep() 5 36 10
A initPopulation() 0 3 2
A __init__() 14 14 1
A tryEval() 0 6 2
A run() 0 7 2
A evalPopulation() 0 5 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
import random as rnd
2
import copy
3
4
__all__ = ['SelfAdaptiveDifferentialEvolutionAlgorithm']
5
6
7
class SolutionjDE(object):
8
    def __init__(self, D, LB, UB):
9
        self.D = D
10
        self.LB = LB
11
        self.UB = UB
12
        self.F = 0.5
13
        self.CR = 0.9
14
        self.Solution = []
15
        self.Fitness = float('inf')
16
        self.generateSolution()
17
18
    def generateSolution(self):
19
        self.Solution = [self.LB + (self.UB - self.LB) * rnd.random()
20
                         for _i in range(self.D)]
21
22 View Code Duplication
    def evaluate(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
23
        self.Fitness = SolutionjDE.FuncEval(self.D, self.Solution)
24
25
    def repair(self):
26
        for i in range(self.D):
27
            if self.Solution[i] > self.UB:
28
                self.Solution[i] = self.UB
29
            if self.Solution[i] < self.LB:
30
                self.Solution[i] = self.LB
31
32
    def __eq__(self, other):
33
        return self.Solution == other.Solution and self.Fitness == other.Fitness
34
35
36
class SelfAdaptiveDifferentialEvolutionAlgorithm(object):
37
    """Self-adaptive differential evolution algorithm.
38
39
    Date: 7. 2. 2018
40
41
    Authors : Uros Mlakar
42
43
    License: MIT
44
45
    Reference paper: Brest, J., Greiner, S., Boskovic, B., Mernik, M., Zumer, V. Self-adapting control
46
    parameters in differential evolution: A comparative study on numerical benchmark problems.
47
    IEEE transactions on evolutionary computation, 10(6), 646-657, 2006.
48
    """
49
50 View Code Duplication
    def __init__(self, D, NP, nFES, Lower, Upper, function):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
51
        # TODO: check for F and CR parameters!
52
        self.D = D  # dimension of problem
53
        self.Np = NP  # population size
54
        self.nFES = nFES  # number of function evaluations
55
        self.Lower = Lower  # lower bound
56
        self.Upper = Upper  # upper bound
57
58
        SolutionjDE.FuncEval = staticmethod(function)
59
        self.Population = []
60
        self.FEs = 0
61
        self.Done = False
62
        self.bestSolution = SolutionjDE(self.D, Lower, Upper)
63
        self.Tao = None  # EDITED: check please
64
65
    def evalPopulation(self):
66
        for p in self.Population:
67
            p.evaluate()
68
            if p.Fitness < self.bestSolution.Fitness:
69
                self.bestSolution = copy.deepcopy(p)
70
71
    def initPopulation(self):
72
        for _i in range(self.Np):
73
            self.Population.append(SolutionjDE(self.D, self.Lower, self.Upper))
74
75
    def tryEval(self, v):
76
        if self.FEs <= self.nFES:
77
            v.evaluate()
78
            self.FEs += 1
79
        else:
80
            self.Done = True
81
82
    def generationStep(self, Population):
83
        newPopulation = []
84
        for i in range(self.Np):
85
            newSolution = SolutionjDE(self.D, self.Lower, self.Upper)
86
87
            if rnd.random() < self.Tao:
88
                newSolution.F = rnd.random()
89
            else:
90
                newSolution.F = Population[i].F
91
92
            if rnd.random() < self.Tao:
93
                newSolution.CR = rnd.random()
94
            else:
95
                newSolution.CR = Population[i].CR
96
97
            r = rnd.sample(range(0, self.Np), 3)
98
            while i in r:
99 View Code Duplication
                r = rnd.sample(range(0, self.Np), 3)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
100
            jrand = int(rnd.random() * self.Np)
101
102
            for j in range(self.D):
103
                if rnd.random() < newSolution.CR or j == jrand:
104
                    newSolution.Solution[j] = Population[r[0]].Solution[j] + newSolution.F * (
105
                        Population[r[1]].Solution[j] - Population[r[2]].Solution[j])
106
                else:
107
                    newSolution.Solution[j] = Population[i].Solution[j]
108
            newSolution.repair()
109
            self.tryEval(newSolution)
110
111
            if newSolution.Fitness < self.bestSolution.Fitness:
112
                self.bestSolution = copy.deepcopy(newSolution)
113
            if newSolution.Fitness < self.Population[i].Fitness:
114
                newPopulation.append(newSolution)
115
            else:
116
                newPopulation.append(Population[i])
117
        return newPopulation
118
119
    def run(self):
120
        self.initPopulation()
121
        self.evalPopulation()
122
        self.FEs = self.Np
123
        while not self.Done:
124
            self.Population = self.generationStep(self.Population)
125
        return self.bestSolution.Fitness
126