Passed
Pull Request — master (#137)
by
unknown
02:01
created

DifferentialEvolutionAlgorithm.tryEval()   A

Complexity

Conditions 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
1
import random as rnd
2
import copy
3
from NiaPy.benchmarks.utility import Utility
4
5
__all__ = ['DifferentialEvolutionAlgorithm']
6
7
8 View Code Duplication
class SolutionDE(object):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
9
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 = SolutionDE.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
37
class DifferentialEvolutionAlgorithm(object):
38
    r"""Implementation of Differential evolution algorithm.
39
40
    **Algorithm:** Differential evolution algorithm
41
42
    **Date:** 2018
43
44
    **Author:** Uros Mlakar
45
46
    **License:** MIT
47
48
    **Reference paper:**
49
        Storn, Rainer, and Kenneth Price. "Differential evolution - a simple and
50
        efficient heuristic for global optimization over continuous spaces."
51
        Journal of global optimization 11.4 (1997): 341-359.
52
    """
53
54 View Code Duplication
    def __init__(self, D, NP, nFES, F, CR, benchmark):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
55
        r"""**__init__(self, D, NP, nFES, F, CR, benchmark)**.
56
57
        Arguments:
58
            D {integer} -- dimension of problem
59
60
            NP {integer} -- population size
61
62
            nFES {integer} -- number of function evaluations
63
64
            F {decimal} -- scaling factor
65
66
            CR {decimal} -- crossover rate
67
68
            benchmark {object} -- benchmark implementation object
69
70
        Raises:
71
            TypeError -- Raised when given benchmark function which does not exists.
72
73
        """
74
75
        self.benchmark = Utility().get_benchmark(benchmark)
76
        self.D = D  # dimension of problem
77
        self.Np = NP  # population size
78
        self.nFES = nFES  # number of function evaluations
79
        self.F = F  # scaling factor
80
        self.CR = CR  # crossover rate
81
        self.Lower = self.benchmark.Lower  # lower bound
82
        self.Upper = self.benchmark.Upper  # upper bound
83
84
        SolutionDE.FuncEval = staticmethod(self.benchmark.function())
85
        self.FEs = 0
86
        self.Done = False
87
        self.Population = []
88
        self.bestSolution = SolutionDE(self.D, self.Lower, self.Upper)
89
90
    def evalPopulation(self):
91
        """Evaluate population."""
92
93
        for p in self.Population:
94
            p.evaluate()
95
            if p.Fitness < self.bestSolution.Fitness:
96
                self.bestSolution = copy.deepcopy(p)
97
98
    def initPopulation(self):
99
        """Initialize population."""
100
101
        for _i in range(self.Np):
102
            self.Population.append(SolutionDE(self.D, self.Lower, self.Upper))
103
104
    def tryEval(self, v):
105
        """Check evaluations."""
106
        if self.FEs <= self.nFES:
107
            v.evaluate()
108
            self.FEs += 1
109
        else:
110
            self.Done = True
111
112
    def generationStep(self, Population):
113
        """Implement main generation step."""
114
115 View Code Duplication
        newPopulation = []
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
116
        for i in range(self.Np):
117
            newSolution = SolutionDE(self.D, self.Lower, self.Upper)
118
119
            r = rnd.sample(range(0, self.Np), 3)
120
            while i in r:
121
                r = rnd.sample(range(0, self.Np), 3)
122
            jrand = int(rnd.random() * self.Np)
123
124
            for j in range(self.D):
125
                if rnd.random() < self.CR or j == jrand:
126
                    newSolution.Solution[j] = Population[r[0]].Solution[j] + self.F * \
127
                        (Population[r[1]].Solution[j] - Population[r[2]].Solution[j])
128
                else:
129
                    newSolution.Solution[j] = Population[i].Solution[j]
130
            newSolution.repair()
131
            self.tryEval(newSolution)
132
133
            if newSolution.Fitness < self.bestSolution.Fitness:
134
                self.bestSolution = copy.deepcopy(newSolution)
135
            if newSolution.Fitness < self.Population[i].Fitness:
136
                newPopulation.append(newSolution)
137
            else:
138
                newPopulation.append(Population[i])
139
        return newPopulation
140
141
    def run(self):
142
        """Run."""
143
        self.initPopulation()
144
        self.evalPopulation()
145
        self.FEs = self.Np
146
        while not self.Done:
147
            self.Population = self.generationStep(self.Population)
148
        return self.bestSolution.Fitness
149