ecabc 3.0.1__tar.gz → 3.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2018 Sanskriti Sharma, Hernan Gelaf-Romer
3
+ Copyright (c) 2018-2026 Sanskriti Sharma, Hernan Gelaf-Romer, Travis Kessler
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,23 +1,41 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: ecabc
3
- Version: 3.0.1
3
+ Version: 3.0.2
4
4
  Summary: Artificial bee colony for function parameter optimization
5
5
  Author-email: Sanskriti Sharma <Sanskriti_Sharma@student.uml.edu>, Hernan Gelaf-Romer <Hernan_Gelafromer@student.uml.edu>, Travis Kessler <travis.j.kessler@gmail.com>
6
+ License: MIT
6
7
  Project-URL: Homepage, https://github.com/ecrl/ecabc
7
8
  Project-URL: Bug Tracker, https://github.com/ecrl/ecabc/issues
9
+ Classifier: Programming Language :: Python :: 3.10
8
10
  Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
9
13
  Classifier: License :: OSI Approved :: MIT License
10
14
  Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.11
15
+ Requires-Python: >=3.10
12
16
  Description-Content-Type: text/markdown
13
17
  License-File: LICENSE
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest>=8; extra == "dev"
20
+ Requires-Dist: pytest-cov>=5; extra == "dev"
21
+ Requires-Dist: ruff>=0.8; extra == "dev"
22
+ Requires-Dist: mypy>=1.8; extra == "dev"
23
+ Requires-Dist: pre-commit>=4; extra == "dev"
24
+ Requires-Dist: build>=1.2; extra == "dev"
25
+ Provides-Extra: docs
26
+ Requires-Dist: sphinx>=7; extra == "docs"
27
+ Requires-Dist: furo>=2024.1; extra == "docs"
28
+ Requires-Dist: sphinx-autodoc-typehints>=2; extra == "docs"
29
+ Requires-Dist: sphinx-copybutton>=0.5; extra == "docs"
30
+ Dynamic: license-file
14
31
 
15
32
  [![UML Energy & Combustion Research Laboratory](https://sites.uml.edu/hunter-mack/files/2021/11/ECRL_final.png)](http://faculty.uml.edu/Hunter_Mack/)
16
33
 
17
- # ECabc: optimization algorithm for tuning user-defined parametric functions
34
+ # ECabc: optimization algorithm for tuning user-defined parametric functions
18
35
  [![GitHub version](https://badge.fury.io/gh/ECRL%2FECabc.svg)](https://badge.fury.io/gh/ECRL%2FECabc)
19
36
  [![PyPI version](https://badge.fury.io/py/ecabc.svg)](https://badge.fury.io/py/ecabc)
20
37
  [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ECRL/ecabc/blob/master/LICENSE)
38
+ [![CI](https://github.com/ecrl/ecabc/actions/workflows/run_tests.yml/badge.svg?branch=master)](https://github.com/ecrl/ecabc/actions/workflows/run_tests.yml)
21
39
  [![DOI](http://joss.theoj.org/papers/10.21105/joss.01420/status.svg)](https://doi.org/10.21105/joss.01420)
22
40
 
23
41
  **ECabc** is an open source Python package used to tune parameters for user-supplied functions based on the [Artificial Bee Colony by D. Karaboğa](http://scholarpedia.org/article/Artificial_bee_colony_algorithm). ECabc optimizes user supplied functions, or **fitness function**s, using a set of variables that exist within a search space. The bee colony consists of three types of bees: employers, onlookers and scouts. An **employer bee** exploits a solution comprised of a permutation of the variables in the search space, and evaluates the viability of the solution. An **onlooker bee** chooses an employer bee with an optimal solution and searches for new solutions near them. The **scout bee**, a variant of the employer bee, will search for a new solution if it has stayed too long at its current solution.
@@ -31,38 +49,35 @@ While it has several applications, ECabc has been successfully used by the Energ
31
49
 
32
50
  # Installation
33
51
 
34
- ### Prerequisites:
35
- - Have python 3.X installed
36
- - Have the ability to install python packages
52
+ **Requires Python 3.10 or newer.** ECabc has no runtime third-party dependencies
53
+ (stdlib only). A virtual environment is recommended.
37
54
 
38
55
  ### Method 1: pip
39
- If you are working in a Linux/Mac environment:
40
- ```
41
- sudo pip install ecabc
42
- ```
43
56
 
44
- Alternatively, in a Windows or virtualenv environment:
45
57
  ```
46
58
  pip install ecabc
47
59
  ```
48
60
 
49
- To update your version of ECabc to the latest release version, use
61
+ To upgrade to the latest release:
62
+
50
63
  ```
51
64
  pip install --upgrade ecabc
52
65
  ```
53
66
 
54
- Note: if multiple Python releases are installed on your system (e.g. 2.7 and 3.7), you may need to execute the correct version of pip. For Python 3.X, change **"pip install ecabc"** to **"pip3 install ecabc"**.
55
-
56
67
  ### Method 2: From source
57
- - Download the ECabc repository, navigate to the download location on the command line/terminal, and execute:
68
+
69
+ Clone or download this repository, then from the repository root:
70
+
58
71
  ```
59
72
  pip install .
60
73
  ```
61
74
 
62
- There are currently no additional dependencies for ECabc.
63
-
64
75
  # Usage
65
76
 
77
+ API stability for the public surface is documented in
78
+ [API_STABILITY.md](API_STABILITY.md) (also the Sphinx *API stability policy*
79
+ page under `docs/source/stability.rst`).
80
+
66
81
  To start using ECabc, you need a couple items:
67
82
  - a fitness function (cost function) to optimize
68
83
  - parameters used by the fitness function
@@ -1,9 +1,10 @@
1
1
  [![UML Energy & Combustion Research Laboratory](https://sites.uml.edu/hunter-mack/files/2021/11/ECRL_final.png)](http://faculty.uml.edu/Hunter_Mack/)
2
2
 
3
- # ECabc: optimization algorithm for tuning user-defined parametric functions
3
+ # ECabc: optimization algorithm for tuning user-defined parametric functions
4
4
  [![GitHub version](https://badge.fury.io/gh/ECRL%2FECabc.svg)](https://badge.fury.io/gh/ECRL%2FECabc)
5
5
  [![PyPI version](https://badge.fury.io/py/ecabc.svg)](https://badge.fury.io/py/ecabc)
6
6
  [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ECRL/ecabc/blob/master/LICENSE)
7
+ [![CI](https://github.com/ecrl/ecabc/actions/workflows/run_tests.yml/badge.svg?branch=master)](https://github.com/ecrl/ecabc/actions/workflows/run_tests.yml)
7
8
  [![DOI](http://joss.theoj.org/papers/10.21105/joss.01420/status.svg)](https://doi.org/10.21105/joss.01420)
8
9
 
9
10
  **ECabc** is an open source Python package used to tune parameters for user-supplied functions based on the [Artificial Bee Colony by D. Karaboğa](http://scholarpedia.org/article/Artificial_bee_colony_algorithm). ECabc optimizes user supplied functions, or **fitness function**s, using a set of variables that exist within a search space. The bee colony consists of three types of bees: employers, onlookers and scouts. An **employer bee** exploits a solution comprised of a permutation of the variables in the search space, and evaluates the viability of the solution. An **onlooker bee** chooses an employer bee with an optimal solution and searches for new solutions near them. The **scout bee**, a variant of the employer bee, will search for a new solution if it has stayed too long at its current solution.
@@ -17,38 +18,35 @@ While it has several applications, ECabc has been successfully used by the Energ
17
18
 
18
19
  # Installation
19
20
 
20
- ### Prerequisites:
21
- - Have python 3.X installed
22
- - Have the ability to install python packages
21
+ **Requires Python 3.10 or newer.** ECabc has no runtime third-party dependencies
22
+ (stdlib only). A virtual environment is recommended.
23
23
 
24
24
  ### Method 1: pip
25
- If you are working in a Linux/Mac environment:
26
- ```
27
- sudo pip install ecabc
28
- ```
29
25
 
30
- Alternatively, in a Windows or virtualenv environment:
31
26
  ```
32
27
  pip install ecabc
33
28
  ```
34
29
 
35
- To update your version of ECabc to the latest release version, use
30
+ To upgrade to the latest release:
31
+
36
32
  ```
37
33
  pip install --upgrade ecabc
38
34
  ```
39
35
 
40
- Note: if multiple Python releases are installed on your system (e.g. 2.7 and 3.7), you may need to execute the correct version of pip. For Python 3.X, change **"pip install ecabc"** to **"pip3 install ecabc"**.
41
-
42
36
  ### Method 2: From source
43
- - Download the ECabc repository, navigate to the download location on the command line/terminal, and execute:
37
+
38
+ Clone or download this repository, then from the repository root:
39
+
44
40
  ```
45
41
  pip install .
46
42
  ```
47
43
 
48
- There are currently no additional dependencies for ECabc.
49
-
50
44
  # Usage
51
45
 
46
+ API stability for the public surface is documented in
47
+ [API_STABILITY.md](API_STABILITY.md) (also the Sphinx *API stability policy*
48
+ page under `docs/source/stability.rst`).
49
+
52
50
  To start using ECabc, you need a couple items:
53
51
  - a fitness function (cost function) to optimize
54
52
  - parameters used by the fitness function
@@ -0,0 +1,71 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [tool.setuptools.packages.find]
6
+ where = ["src"]
7
+ exclude = ["paper*"]
8
+
9
+ [project]
10
+ name = "ecabc"
11
+ version = "3.0.2"
12
+ authors = [
13
+ { name="Sanskriti Sharma", email="Sanskriti_Sharma@student.uml.edu" },
14
+ { name="Hernan Gelaf-Romer", email="Hernan_Gelafromer@student.uml.edu" },
15
+ { name="Travis Kessler", email="travis.j.kessler@gmail.com" },
16
+ ]
17
+ description = "Artificial bee colony for function parameter optimization"
18
+ readme = "README.md"
19
+ requires-python = ">=3.10"
20
+ license = { text = "MIT" }
21
+ classifiers = [
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "License :: OSI Approved :: MIT License",
27
+ "Operating System :: OS Independent",
28
+ ]
29
+
30
+ [project.urls]
31
+ "Homepage" = "https://github.com/ecrl/ecabc"
32
+ "Bug Tracker" = "https://github.com/ecrl/ecabc/issues"
33
+
34
+ [project.optional-dependencies]
35
+ dev = [
36
+ "pytest>=8",
37
+ "pytest-cov>=5",
38
+ "ruff>=0.8",
39
+ "mypy>=1.8",
40
+ "pre-commit>=4",
41
+ "build>=1.2",
42
+ ]
43
+ docs = [
44
+ "sphinx>=7",
45
+ "furo>=2024.1",
46
+ "sphinx-autodoc-typehints>=2",
47
+ "sphinx-copybutton>=0.5",
48
+ ]
49
+
50
+ [tool.ruff]
51
+ line-length = 88
52
+ src = ["src", "tests"]
53
+
54
+ [tool.ruff.lint]
55
+ select = ["E", "F", "I", "UP"]
56
+
57
+ [tool.pytest.ini_options]
58
+ addopts = "--cov=ecabc --cov-report=term-missing --cov-fail-under=95"
59
+ testpaths = ["tests"]
60
+
61
+ [tool.coverage.run]
62
+ source = ["ecabc"]
63
+ branch = false
64
+
65
+ [tool.mypy]
66
+ python_version = "3.10"
67
+ files = ["src/ecabc"]
68
+ warn_return_any = true
69
+ warn_unused_configs = true
70
+ check_untyped_defs = true
71
+ disallow_untyped_defs = false
@@ -0,0 +1,19 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ from ecabc.abc import ABC
4
+ from ecabc.bee import Bee
5
+ from ecabc.parameter import Parameter
6
+
7
+ from . import utils as utils
8
+
9
+ __all__ = ["ABC", "Bee", "Parameter", "__version__", "utils"]
10
+
11
+
12
+ def _resolve_version() -> str:
13
+ try:
14
+ return version("ecabc")
15
+ except PackageNotFoundError:
16
+ return "0.0.0+unknown"
17
+
18
+
19
+ __version__ = _resolve_version()
@@ -0,0 +1,305 @@
1
+ #!/usr/bin/env python
2
+ #
3
+ # ecabc/abc.py
4
+ # v.3.0.0
5
+ #
6
+ # Developed in 2019 by Sanskriti Sharma <sanskriti_sharma@student.uml.edu>,
7
+ # Hernan Gelaf-Romer <hernan_gelafromer@student.uml.edu>, and Travis Kessler
8
+ # <Travis_Kessler@student.uml.edu>
9
+ #
10
+ # abc.py: contains ABC object, handling the initialization and runtime of the
11
+ # artificial bee colony
12
+ #
13
+
14
+ # Stdlib. imports
15
+ from collections.abc import Callable
16
+ from multiprocessing import Pool
17
+ from typing import Any
18
+ from warnings import warn
19
+
20
+ # ECabc imports
21
+ from ecabc.bee import Bee
22
+ from ecabc.parameter import Parameter
23
+ from ecabc.utils import apply_mutation, call_obj_fn, choose_bee, determine_best_bee
24
+
25
+
26
+ class ABC:
27
+ def __init__(
28
+ self,
29
+ num_employers: int,
30
+ objective_fn: Callable[[list], float],
31
+ obj_fn_args: dict = {},
32
+ num_processes: int = 1,
33
+ ):
34
+ """ABC object: optimizes parameters for user-supplied function
35
+
36
+ Args:
37
+ num_employers (int): number of employer bees in the colony
38
+ objective_fn (callable): function to optimize; accepts list of
39
+ ints/floats, returns float (fitness)
40
+ obj_fn_args (dict): non-tunable kwargs to pass to objective_fn
41
+ num_processes (int): number of concurrent processes to utilize
42
+ """
43
+
44
+ if not callable(objective_fn):
45
+ raise ReferenceError("Supplied objective function not callable")
46
+ self._obj_fn = objective_fn
47
+ # Copy so the shared mutable default (and caller-owned dicts) are not aliased.
48
+ self._obj_fn_args = dict(obj_fn_args)
49
+ self._num_employers = num_employers
50
+ self._num_processes = num_processes
51
+ self._params: list[Parameter] = []
52
+ self._bees: list[Bee] = []
53
+
54
+ @property
55
+ def best_fitness(self) -> float:
56
+ """Returns fitness score from best-performing bee"""
57
+
58
+ return determine_best_bee(self._bees)[0]
59
+
60
+ @property
61
+ def best_ret_val(self) -> int | float | None:
62
+ """Returns objective_fn return value from best-performing bee"""
63
+
64
+ return determine_best_bee(self._bees)[1]
65
+
66
+ @property
67
+ def best_params(self) -> dict:
68
+ """Returns parameters from best-performing bee"""
69
+
70
+ vals = determine_best_bee(self._bees)[2]
71
+ ret_val: dict[str, int | float] = {}
72
+ if vals is None:
73
+ return ret_val
74
+ for idx, param in enumerate(self._params):
75
+ if param._name is None:
76
+ ret_val[f"P{idx}"] = vals[idx]
77
+ else:
78
+ ret_val[param._name] = vals[idx]
79
+ return ret_val
80
+
81
+ @property
82
+ def average_fitness(self) -> float | None:
83
+ """Returns average fitness score for bee population"""
84
+
85
+ if len(self._bees) == 0:
86
+ return None
87
+ return sum(b._fitness_score for b in self._bees) / len(self._bees)
88
+
89
+ @property
90
+ def average_ret_val(self) -> int | float | None:
91
+ """Returns average objective_fn return value for bee population"""
92
+
93
+ if len(self._bees) == 0:
94
+ return None
95
+ return sum(b._obj_fn_val for b in self._bees) / len(self._bees)
96
+
97
+ def add_param(
98
+ self,
99
+ min_val: int | float,
100
+ max_val: int | float,
101
+ restrict: bool = True,
102
+ name: str | None = None,
103
+ ):
104
+ """ABC.add_param: adds a parameter to be processed by the user-
105
+ supplied objective function
106
+
107
+ Args:
108
+ min_val (int, float): minimum value allowed for the parameter's
109
+ initialization
110
+ max_val (int, float): maximum value allowed for the parameter's
111
+ initialization
112
+ restrict (bool): if `True`, parameter mutations must be within
113
+ [min_val, max_val], `False` allows out-of-bounds mutation
114
+ name (str): name of parameter, optional
115
+ """
116
+
117
+ if len(self._bees) > 0:
118
+ raise RuntimeError("Cannot add another parameter after bee initialization")
119
+ self._params.append(Parameter(min_val, max_val, restrict, name))
120
+
121
+ def initialize(self):
122
+ """ABC.initialize: creates `num_employers` employer bees and
123
+ `num_employers` onlooker bees
124
+ """
125
+
126
+ if len(self._bees) > 0:
127
+ warn(
128
+ "initialize() called again: overwriting bee population", RuntimeWarning
129
+ )
130
+
131
+ self._bees = []
132
+
133
+ if self._num_processes > 1:
134
+ employer_pool = Pool(processes=self._num_processes)
135
+ employer_results: list[Any] = []
136
+
137
+ for _ in range(self._num_employers):
138
+ params = [p.rand_val for p in self._params]
139
+ if self._num_processes > 1:
140
+ employer_results.append(
141
+ employer_pool.apply_async(
142
+ call_obj_fn, [params, self._obj_fn, self._obj_fn_args]
143
+ )
144
+ )
145
+ else:
146
+ employer_results.append(
147
+ call_obj_fn(params, self._obj_fn, self._obj_fn_args)
148
+ )
149
+
150
+ if self._num_processes > 1:
151
+ employer_pool.close()
152
+ employer_pool.join()
153
+ employer_results = [r.get() for r in employer_results]
154
+
155
+ for result in employer_results:
156
+ self._bees.append(
157
+ Bee(result[0], result[1], len(self._params) * self._num_employers, True)
158
+ )
159
+
160
+ if self._num_processes > 1:
161
+ onlooker_pool = Pool(processes=self._num_processes)
162
+ onlooker_results: list[Any] = []
163
+
164
+ for _ in range(self._num_employers):
165
+ chosen_employer = choose_bee(self._bees)
166
+ neighbor_food = apply_mutation(chosen_employer._params, self._params)
167
+
168
+ if self._num_processes > 1:
169
+ onlooker_results.append(
170
+ onlooker_pool.apply_async(
171
+ call_obj_fn, [neighbor_food, self._obj_fn, self._obj_fn_args]
172
+ )
173
+ )
174
+ else:
175
+ onlooker_results.append(
176
+ call_obj_fn(neighbor_food, self._obj_fn, self._obj_fn_args)
177
+ )
178
+
179
+ if self._num_processes > 1:
180
+ onlooker_pool.close()
181
+ onlooker_pool.join()
182
+ onlooker_results = [r.get() for r in onlooker_results]
183
+
184
+ for result in onlooker_results:
185
+ self._bees.append(
186
+ Bee(
187
+ result[0],
188
+ result[1],
189
+ len(self._params) * self._num_employers,
190
+ )
191
+ )
192
+
193
+ def search(self):
194
+ """Perform one search cycle for all bees in the colony.
195
+
196
+ For each bee: if it has exhausted its current food source, an employer
197
+ finds a new random food source and an onlooker travels near a
198
+ well-performing bee; otherwise one parameter is mutated and the bee
199
+ moves only if the neighbor food is better. The colony is then replaced
200
+ with the updated bee states.
201
+
202
+ Exhaustion is the maximum number of search cycles a bee may stay at its
203
+ current food source, ``EX = NE * D``, where ``NE`` is the number of
204
+ employers and ``D`` is the number of parameters.
205
+ """
206
+
207
+ if len(self._bees) == 0:
208
+ raise RuntimeError("search() cannot be called before initialize()")
209
+
210
+ if self._num_processes > 1:
211
+ bee_pool = Pool(processes=self._num_processes)
212
+ new_employer_results: list[Any] = []
213
+ new_onlooker_results: list[Any] = []
214
+ new_position_results: list[Any] = []
215
+ current_positions: list[Bee] = []
216
+
217
+ for bee in self._bees:
218
+ if bee.abandon:
219
+ if bee._is_employer:
220
+ new_params = [p.rand_val for p in self._params]
221
+ if self._num_processes > 1:
222
+ new_employer_results.append(
223
+ bee_pool.apply_async(
224
+ call_obj_fn,
225
+ [new_params, self._obj_fn, self._obj_fn_args],
226
+ )
227
+ )
228
+ else:
229
+ new_employer_results.append(
230
+ call_obj_fn(new_params, self._obj_fn, self._obj_fn_args)
231
+ )
232
+
233
+ else:
234
+ chosen_bee = choose_bee(self._bees)
235
+ neighbor_food = apply_mutation(chosen_bee._params, self._params)
236
+ if self._num_processes > 1:
237
+ new_onlooker_results.append(
238
+ bee_pool.apply_async(
239
+ call_obj_fn,
240
+ [neighbor_food, self._obj_fn, self._obj_fn_args],
241
+ )
242
+ )
243
+ else:
244
+ new_onlooker_results.append(
245
+ call_obj_fn(neighbor_food, self._obj_fn, self._obj_fn_args)
246
+ )
247
+
248
+ else:
249
+ current_positions.append(bee)
250
+ neighbor_food = apply_mutation(bee._params, self._params)
251
+ if self._num_processes > 1:
252
+ new_position_results.append(
253
+ bee_pool.apply_async(
254
+ call_obj_fn,
255
+ [neighbor_food, self._obj_fn, self._obj_fn_args],
256
+ )
257
+ )
258
+ else:
259
+ new_position_results.append(
260
+ call_obj_fn(neighbor_food, self._obj_fn, self._obj_fn_args)
261
+ )
262
+
263
+ if self._num_processes > 1:
264
+ bee_pool.close()
265
+ bee_pool.join()
266
+ new_employer_results = [r.get() for r in new_employer_results]
267
+ new_onlooker_results = [r.get() for r in new_onlooker_results]
268
+ new_position_results = [r.get() for r in new_position_results]
269
+
270
+ next_bee_generation = []
271
+
272
+ for result in new_employer_results:
273
+ next_bee_generation.append(
274
+ Bee(result[0], result[1], len(self._params) * self._num_employers, True)
275
+ )
276
+
277
+ for result in new_onlooker_results:
278
+ next_bee_generation.append(
279
+ Bee(result[0], result[1], len(self._params) * self._num_employers)
280
+ )
281
+
282
+ for idx, result in enumerate(new_position_results):
283
+ bee_to_compare = current_positions[idx]
284
+ if bee_to_compare.is_better_food(result[1]):
285
+ if bee_to_compare._is_employer:
286
+ next_bee_generation.append(
287
+ Bee(
288
+ result[0],
289
+ result[1],
290
+ len(self._params) * self._num_employers,
291
+ True,
292
+ )
293
+ )
294
+ else:
295
+ next_bee_generation.append(
296
+ Bee(
297
+ result[0],
298
+ result[1],
299
+ len(self._params) * self._num_employers,
300
+ )
301
+ )
302
+ else:
303
+ next_bee_generation.append(bee_to_compare)
304
+
305
+ self._bees = next_bee_generation
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
2
  #
4
3
  # ecabc/bee.py
5
4
  # v.3.0.0
@@ -13,14 +12,17 @@
13
12
  #
14
13
 
15
14
  # Stdlib. imports
16
- from typing import Union
17
15
 
18
16
 
19
17
  class Bee:
20
-
21
- def __init__(self, params: list, obj_fn_val: Union[int, float],
22
- stay_limit: int, is_employer: bool = False):
23
- ''' Bee object: houses bee-specific information such as its current
18
+ def __init__(
19
+ self,
20
+ params: list,
21
+ obj_fn_val: int | float,
22
+ stay_limit: int,
23
+ is_employer: bool = False,
24
+ ):
25
+ """Bee object: houses bee-specific information such as its current
24
26
  set of parameters, the objective function value resulting from its,
25
27
  current parameters, maximum number of cycles it can stay at its
26
28
  current food source, and whether it is an employer bee or not
@@ -32,7 +34,7 @@ class Bee:
32
34
  stay_limit (int): maximum number of cycles the bee can stay at its
33
35
  current food source
34
36
  is_employer (bool): `True` if employer, `False` if onlooker
35
- '''
37
+ """
36
38
 
37
39
  self._params = params
38
40
  self._obj_fn_val = obj_fn_val
@@ -43,9 +45,9 @@ class Bee:
43
45
 
44
46
  @property
45
47
  def abandon(self) -> bool:
46
- ''' When called, increment how many times the bee has stayed at its
48
+ """When called, increment how many times the bee has stayed at its
47
49
  current food source; if reached stay limit, return `True` else `False`
48
- '''
50
+ """
49
51
 
50
52
  self._stay_count += 1
51
53
  if self._stay_count >= self._stay_limit:
@@ -54,8 +56,8 @@ class Bee:
54
56
  return False
55
57
 
56
58
  @staticmethod
57
- def calc_fitness(obj_fn_val: Union[int, float]) -> float:
58
- ''' Static method: Bee.calc_fitness: Calculates fitness score based on
59
+ def calc_fitness(obj_fn_val: int | float) -> float:
60
+ """Static method: Bee.calc_fitness: Calculates fitness score based on
59
61
  objective function value, using the equation:
60
62
 
61
63
  fitness = 1 / (1 + ofv) if ofv >= 0
@@ -69,15 +71,15 @@ class Bee:
69
71
 
70
72
  Returns:
71
73
  float: resulting fitness score
72
- '''
74
+ """
73
75
 
74
76
  if obj_fn_val >= 0:
75
77
  return 1 / (obj_fn_val + 1)
76
78
  else:
77
79
  return 1 + abs(obj_fn_val)
78
80
 
79
- def is_better_food(self, obj_fn_val: Union[int, float]) -> bool:
80
- ''' Bee.is_better_food: determines if objective function value
81
+ def is_better_food(self, obj_fn_val: int | float) -> bool:
82
+ """Bee.is_better_food: determines if objective function value
81
83
  resulting from a new food source is better than the bee's current food
82
84
  source
83
85
 
@@ -87,7 +89,7 @@ class Bee:
87
89
 
88
90
  Returns:
89
91
  bool: `True` if better food source else `False`
90
- '''
92
+ """
91
93
 
92
94
  if self.calc_fitness(obj_fn_val) > self._fitness_score:
93
95
  return True