Completed
Push — master ( cc7745...279fb5 )
by Grega
19s queued 17s
created

NiaPy.algorithms.basic.abc   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 18
eloc 64
dl 0
loc 183
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
D ArtificialBeeColonyAlgorithm.runIteration() 0 54 12
A SolutionABC.__init__() 0 10 1
A ArtificialBeeColonyAlgorithm.CalculateProbs() 0 14 1
A ArtificialBeeColonyAlgorithm.initPopulation() 0 20 1
A ArtificialBeeColonyAlgorithm.setParameters() 0 12 1
A ArtificialBeeColonyAlgorithm.typeParameters() 0 14 2
1
# encoding=utf8
2
import copy
3
import logging
4
5
from numpy import asarray, full, argmax
6
7
from NiaPy.algorithms.algorithm import Algorithm, Individual, defaultIndividualInit
8
9
logging.basicConfig()
10
logger = logging.getLogger('NiaPy.algorithms.basic')
11
logger.setLevel('INFO')
12
13
__all__ = ['ArtificialBeeColonyAlgorithm']
14
15
class SolutionABC(Individual):
16
	r"""Representation of solution for Artificial Bee Colony Algorithm.
17
18
	Date:
19
		2018
20
21
	Author:
22
		Klemen Berkovič
23
24
	See Also:
25
		* :class:`NiaPy.algorithms.Individual`
26
	"""
27
	def __init__(self, **kargs):
28
		r"""Initialize individual.
29
30
		Args:
31
			kargs (Dict[str, Any]): Additional arguments.
32
33
		See Also:
34
			* :func:`NiaPy.algorithms.Individual.__init__`
35
		"""
36
		Individual.__init__(self, **kargs)
37
38
class ArtificialBeeColonyAlgorithm(Algorithm):
39
	r"""Implementation of Artificial Bee Colony algorithm.
40
41
	Algorithm:
42
		Artificial Bee Colony algorithm
43
44
	Date:
45
		2018
46
47
	Author:
48
		Uros Mlakar and Klemen Berkovič
49
50
	License:
51
		MIT
52
53
	Reference paper:
54
		Karaboga, D., and Bahriye B. "A powerful and efficient algorithm for numerical function optimization: artificial bee colony (ABC) algorithm." Journal of global optimization 39.3 (2007): 459-471.
55
56
	Arguments
57
		Name (List[str]): List containing strings that represent algorithm names
58
		Limit (Union[float, numpy.ndarray[float]]): Limt
59
60
	See Also:
61
		* :class:`NiaPy.algorithms.Algorithm`
62
	"""
63
	Name = ['ArtificialBeeColonyAlgorithm', 'ABC']
64
65
	@staticmethod
66
	def typeParameters():
67
		r"""Return functions for checking values of parameters.
68
69
		Returns:
70
			Dict[str, Callable]:
71
				* Limit (Callable[Union[float, numpy.ndarray[float]]]): TODO
72
73
		See Also:
74
			* :func:`NiaPy.algorithms.Algorithm.typeParameters`
75
		"""
76
		d = Algorithm.typeParameters()
77
		d.update({'Limit': lambda x: isinstance(x, int) and x > 0})
78
		return d
79
80
	def setParameters(self, NP=10, Limit=100, **ukwargs):
81
		r"""Set the parameters of Artificial Bee Colony Algorithm.
82
83
		Parameters:
84
			Limit (Optional[Union[float, numpy.ndarray[float]]]): Limt
85
			**ukwargs (Dict[str, Any]): Additional arguments
86
87
		See Also:
88
			* :func:`NiaPy.algorithms.Algorithm.setParameters`
89
		"""
90
		Algorithm.setParameters(self, NP=NP, InitPopFunc=defaultIndividualInit, itype=SolutionABC, **ukwargs)
91
		self.FoodNumber, self.Limit = int(self.NP / 2), Limit
92
93
	def CalculateProbs(self, Foods, Probs):
94
		r"""Calculate the probes.
95
96
		Parameters:
97
			Foods (numpy.ndarray): TODO
98
			Probs (numpy.ndarray): TODO
99
100
		Returns:
101
			numpy.ndarray: TODO
102
		"""
103
		Probs = [1.0 / (Foods[i].f + 0.01) for i in range(self.FoodNumber)]
104
		s = sum(Probs)
105
		Probs = [Probs[i] / s for i in range(self.FoodNumber)]
106
		return Probs
107
108
	def initPopulation(self, task):
109
		r"""Initialize the starting population.
110
111
		Parameters:
112
			task (Task): Optimization task
113
114
		Returns:
115
			Tuple[numpy.ndarray, numpy.ndarray[float], Dict[str, Any]]:
116
				1. New population
117
				2. New population fitness/function values
118
				3. Additional arguments:
119
					* Probes (numpy.ndarray): TODO
120
					* Trial (numpy.ndarray): TODO
121
122
		See Also:
123
			* :func:`NiaPy.algorithms.Algorithm.initPopulation`
124
		"""
125
		Foods, fpop, _ = Algorithm.initPopulation(self, task)
126
		Probs, Trial = full(self.FoodNumber, 0.0), full(self.FoodNumber, 0.0)
127
		return Foods, fpop, {'Probs': Probs, 'Trial': Trial}
128
129
	def runIteration(self, task, Foods, fpop, xb, fxb, Probs, Trial, **dparams):
130
		r"""Core funciton of  the algorithm.
131
132
		Parameters:
133
			task (Task): Optimization task
134
			Foods (numpy.ndarray): Current population
135
			fpop (numpy.ndarray[float]): Function/fitness values of current population
136
			xb (numpy.ndarray): Current best individual
137
			fxb (float): Current best individual fitness/function value
138
			Probs (numpy.ndarray): TODO
139
			Trial (numpy.ndarray): TODO
140
			dparams (Dict[str, Any]): Additional parameters
141
142
		Returns:
143
			Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]:
144
				1. New population
145
				2. New population fitness/function values
146
				3. New global best solution
147
				4. New global best fitness/objecive value
148
				5. Additional arguments:
149
					* Probes (numpy.ndarray): TODO
150
					* Trial (numpy.ndarray): TODO
151
		"""
152
		for i in range(self.FoodNumber):
153
			newSolution = copy.deepcopy(Foods[i])
154
			param2change = int(self.rand() * task.D)
155
			neighbor = int(self.FoodNumber * self.rand())
156
			newSolution.x[param2change] = Foods[i].x[param2change] + (-1 + 2 * self.rand()) * (Foods[i].x[param2change] - Foods[neighbor].x[param2change])
157
			newSolution.evaluate(task, rnd=self.Rand)
158
			if newSolution.f < Foods[i].f:
159
				Foods[i], Trial[i] = newSolution, 0
160
				if newSolution.f < fxb: xb, fxb = newSolution.x.copy(), newSolution.f
161
			else: Trial[i] += 1
162
		Probs, t, s = self.CalculateProbs(Foods, Probs), 0, 0
163
		while t < self.FoodNumber:
164
			if self.rand() < Probs[s]:
165
				t += 1
166
				Solution = copy.deepcopy(Foods[s])
167
				param2change = int(self.rand() * task.D)
168
				neighbor = int(self.FoodNumber * self.rand())
169
				while neighbor == s: neighbor = int(self.FoodNumber * self.rand())
170
				Solution.x[param2change] = Foods[s].x[param2change] + (-1 + 2 * self.rand()) * (Foods[s].x[param2change] - Foods[neighbor].x[param2change])
171
				Solution.evaluate(task, rnd=self.Rand)
172
				if Solution.f < Foods[s].f:
173
					Foods[s], Trial[s] = Solution, 0
174
					if Solution.f < fxb: xb, fxb = Solution.x.copy(), Solution.f
175
				else: Trial[s] += 1
176
			s += 1
177
			if s == self.FoodNumber: s = 0
178
		mi = argmax(Trial)
179
		if Trial[mi] >= self.Limit:
180
			Foods[mi], Trial[mi] = SolutionABC(task=task, rnd=self.Rand), 0
181
			if Foods[mi].f < fxb: xb, fxb = Foods[mi].x.copy(), Foods[mi].f
182
		return Foods, asarray([f.f for f in Foods]), xb, fxb, {'Probs': Probs, 'Trial': Trial}
183
184
# vim: tabstop=3 noexpandtab shiftwidth=3 softtabstop=3
185