aisp 0.3.21__tar.gz → 0.4.1__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.
Files changed (44) hide show
  1. {aisp-0.3.21 → aisp-0.4.1}/PKG-INFO +2 -1
  2. {aisp-0.3.21 → aisp-0.4.1}/README.md +1 -0
  3. aisp-0.4.1/aisp/__init__.py +39 -0
  4. aisp-0.4.1/aisp/base/__init__.py +26 -0
  5. {aisp-0.3.21 → aisp-0.4.1}/aisp/base/_classifier.py +4 -2
  6. aisp-0.4.1/aisp/base/_optimizer.py +188 -0
  7. {aisp-0.3.21 → aisp-0.4.1}/aisp/base/mutation.py +85 -17
  8. aisp-0.4.1/aisp/base/populations.py +49 -0
  9. aisp-0.4.1/aisp/csa/__init__.py +20 -0
  10. {aisp-0.3.21 → aisp-0.4.1}/aisp/csa/_cell.py +2 -2
  11. aisp-0.4.1/aisp/csa/_clonalg.py +369 -0
  12. {aisp-0.3.21 → aisp-0.4.1}/aisp/ina/__init__.py +2 -2
  13. {aisp-0.3.21 → aisp-0.4.1}/aisp/ina/_ai_network.py +5 -4
  14. {aisp-0.3.21 → aisp-0.4.1}/aisp/ina/_base.py +0 -40
  15. {aisp-0.3.21 → aisp-0.4.1}/aisp/nsa/__init__.py +7 -0
  16. aisp-0.4.1/aisp/utils/display.py +185 -0
  17. aisp-0.4.1/aisp/utils/sanitizers.py +116 -0
  18. {aisp-0.3.21 → aisp-0.4.1}/aisp/utils/types.py +10 -2
  19. {aisp-0.3.21 → aisp-0.4.1}/aisp.egg-info/PKG-INFO +2 -1
  20. {aisp-0.3.21 → aisp-0.4.1}/aisp.egg-info/SOURCES.txt +4 -0
  21. {aisp-0.3.21 → aisp-0.4.1}/pyproject.toml +1 -1
  22. aisp-0.3.21/aisp/__init__.py +0 -26
  23. aisp-0.3.21/aisp/base/__init__.py +0 -7
  24. aisp-0.3.21/aisp/csa/__init__.py +0 -9
  25. aisp-0.3.21/aisp/utils/sanitizers.py +0 -64
  26. {aisp-0.3.21 → aisp-0.4.1}/LICENSE +0 -0
  27. {aisp-0.3.21 → aisp-0.4.1}/aisp/base/_base.py +0 -0
  28. {aisp-0.3.21 → aisp-0.4.1}/aisp/base/_clusterer.py +0 -0
  29. {aisp-0.3.21 → aisp-0.4.1}/aisp/csa/_ai_recognition_sys.py +0 -0
  30. {aisp-0.3.21 → aisp-0.4.1}/aisp/csa/_base.py +0 -0
  31. {aisp-0.3.21 → aisp-0.4.1}/aisp/exceptions.py +0 -0
  32. {aisp-0.3.21 → aisp-0.4.1}/aisp/nsa/_base.py +0 -0
  33. {aisp-0.3.21 → aisp-0.4.1}/aisp/nsa/_binary_negative_selection.py +0 -0
  34. {aisp-0.3.21 → aisp-0.4.1}/aisp/nsa/_negative_selection.py +0 -0
  35. {aisp-0.3.21 → aisp-0.4.1}/aisp/nsa/_ns_core.py +0 -0
  36. {aisp-0.3.21 → aisp-0.4.1}/aisp/utils/__init__.py +0 -0
  37. {aisp-0.3.21 → aisp-0.4.1}/aisp/utils/_multiclass.py +0 -0
  38. {aisp-0.3.21 → aisp-0.4.1}/aisp/utils/distance.py +0 -0
  39. {aisp-0.3.21 → aisp-0.4.1}/aisp/utils/metrics.py +0 -0
  40. {aisp-0.3.21 → aisp-0.4.1}/aisp/utils/validation.py +0 -0
  41. {aisp-0.3.21 → aisp-0.4.1}/aisp.egg-info/dependency_links.txt +0 -0
  42. {aisp-0.3.21 → aisp-0.4.1}/aisp.egg-info/requires.txt +0 -0
  43. {aisp-0.3.21 → aisp-0.4.1}/aisp.egg-info/top_level.txt +0 -0
  44. {aisp-0.3.21 → aisp-0.4.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aisp
3
- Version: 0.3.21
3
+ Version: 0.4.1
4
4
  Summary: Package with techniques of artificial immune systems.
5
5
  Author-email: João Paulo da Silva Barros <jpsilvabarr@gmail.com>
6
6
  Maintainer-email: Alison Zille Lopes <alisonzille@gmail.com>
@@ -86,6 +86,7 @@ Artificial Immune Systems (AIS) are inspired by the vertebrate immune system, cr
86
86
  > - [x] [**Negative Selection.**](https://ais-package.github.io/docs/aisp-techniques/negative-selection/)
87
87
  > - [x] [**Clonal Selection Algorithms.**](https://ais-package.github.io/docs/aisp-techniques/clonal-selection-algorithms/)
88
88
  > * [AIRS - Artificial Immune Recognition System](https://ais-package.github.io/docs/aisp-techniques/clonal-selection-algorithms/airs/)
89
+ > * [CLONALG - Clonal Selection Algorithm](https://ais-package.github.io/docs/aisp-techniques/clonal-selection-algorithms/clonalg)
89
90
  > - [ ] *Danger Theory.*
90
91
  > - [x] [*Immune Network Theory.*](https://ais-package.github.io/docs/aisp-techniques/immune-network-theory/)
91
92
  > - [AiNet - Artificial Immune Network para Clustering and Compression](https://ais-package.github.io/docs/aisp-techniques/immune-network-theory/ainet)
@@ -51,6 +51,7 @@ Artificial Immune Systems (AIS) are inspired by the vertebrate immune system, cr
51
51
  > - [x] [**Negative Selection.**](https://ais-package.github.io/docs/aisp-techniques/negative-selection/)
52
52
  > - [x] [**Clonal Selection Algorithms.**](https://ais-package.github.io/docs/aisp-techniques/clonal-selection-algorithms/)
53
53
  > * [AIRS - Artificial Immune Recognition System](https://ais-package.github.io/docs/aisp-techniques/clonal-selection-algorithms/airs/)
54
+ > * [CLONALG - Clonal Selection Algorithm](https://ais-package.github.io/docs/aisp-techniques/clonal-selection-algorithms/clonalg)
54
55
  > - [ ] *Danger Theory.*
55
56
  > - [x] [*Immune Network Theory.*](https://ais-package.github.io/docs/aisp-techniques/immune-network-theory/)
56
57
  > - [AiNet - Artificial Immune Network para Clustering and Compression](https://ais-package.github.io/docs/aisp-techniques/immune-network-theory/ainet)
@@ -0,0 +1,39 @@
1
+ """AISP - Artificial Immune Systems Package.
2
+
3
+ AISP is a Python package of immunoinspired techniques that apply metaphors from the vertebrate
4
+ immune system to pattern recognition and optimization tasks.
5
+
6
+ The package is organized into specialized modules, each dedicated to a family of Artificial
7
+ Immune Systems algorithms:
8
+
9
+ Modules
10
+ -------
11
+ csa : Clonal Selection Algorithms.
12
+ Inspired by the processes of antibody proliferation and mutation.
13
+ - AIRS: Artificial Immune Recognition System for classification.
14
+ - Clonalg: Clonal Selection Algorithm for optimization.
15
+
16
+ nsa : Negative Selection Algorithms
17
+ Simulates T cell maturation and is capable of detecting non-self cells.
18
+ - RNSA: Real-value Negative Selection Algorithm for classification.
19
+ - BNSA: Binary Negative Selection Algorithm for classification.
20
+
21
+ ina : Immune Network Algorithms
22
+ Based on immune network theory.
23
+ - AiNet: Artificial Immune Network for clustering.
24
+
25
+ For detailed documentation and examples, visit:
26
+ https://ais-package.github.io/docs/intro
27
+ """
28
+
29
+ from . import csa
30
+ from . import ina
31
+ from . import nsa
32
+
33
+ __author__ = "AISP Development Team"
34
+ __version__ = "0.4.0"
35
+ __all__ = [
36
+ 'csa',
37
+ 'nsa',
38
+ 'ina'
39
+ ]
@@ -0,0 +1,26 @@
1
+ """Base Classes and Core Utilities.
2
+
3
+ This module provides the fundamental classes and utilities that serve as the basis for all
4
+ Artificial Immune Systems algorithms implemented in the AISP package.
5
+
6
+ Classes
7
+ -------
8
+ BaseClassifier
9
+ Abstract Base Class for Classification Algorithms.
10
+ BaseClusterer
11
+ Abstract Base Class for Clustering Algorithms.
12
+ BaseOptimizer
13
+ Abstract Base Class for optimization algorithms.
14
+
15
+ Functions
16
+ ---------
17
+ set_seed_numba
18
+ Set Random Seed for Numba JIT Compilation.
19
+ """
20
+
21
+ from ._base import set_seed_numba
22
+ from ._classifier import BaseClassifier
23
+ from ._clusterer import BaseClusterer
24
+ from ._optimizer import BaseOptimizer
25
+
26
+ __all__ = ['BaseClassifier', 'BaseClusterer', 'BaseOptimizer', 'set_seed_numba']
@@ -13,9 +13,11 @@ from ..utils.metrics import accuracy_score
13
13
 
14
14
 
15
15
  class BaseClassifier(ABC, Base):
16
- """Base class for classification algorithms.
16
+ """Abstract base class for classification algorithms.
17
17
 
18
- Defines the abstract methods ``fit`` and ``predict``, and implements the ``score`` method.
18
+ This class defines the core interface for classification models. It enforces the
19
+ implementation of the ``fit`` and ``predict`` methods in all derived classes,
20
+ and provides a default implementation of ``score`` and utility functions.
19
21
  """
20
22
 
21
23
  classes: Union[npt.NDArray, list] = []
@@ -0,0 +1,188 @@
1
+ """Base class for optimization algorithms."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from typing import Optional, List, Any, Callable
7
+
8
+ from ..utils.display import TableFormatter
9
+
10
+
11
+ class BaseOptimizer(ABC):
12
+ """Abstract base class for optimization algorithms.
13
+
14
+ This class defines the core interface for optimization strategies. It keeps track of cost
15
+ history, evaluated solutions, and the best solution found during the optimization process.
16
+ Subclasses must implement ``optimize`` and ``affinity_function``.
17
+ """
18
+
19
+ def __init__(self) -> None:
20
+ self._cost_history: List[float] = []
21
+ self._solution_history: list = []
22
+ self._best_solution: Optional[Any] = None
23
+ self._best_cost: Optional[float] = None
24
+ self._protected_aliases = [
25
+ "__init__",
26
+ "optimize",
27
+ "register",
28
+ "get_report"
29
+ ]
30
+ self.mode = "min"
31
+
32
+ @property
33
+ def cost_history(self) -> List[float]:
34
+ """Return the history of costs during optimization."""
35
+ return self._cost_history
36
+
37
+ @property
38
+ def solution_history(self) -> List:
39
+ """Returns the history of evaluated solutions."""
40
+ return self._solution_history
41
+
42
+ @property
43
+ def best_solution(self) -> Optional[Any]:
44
+ """Return the best solution found so far, or ``None`` if unavailable."""
45
+ return self._best_solution
46
+
47
+ @property
48
+ def best_cost(self) -> Optional[float]:
49
+ """Return the cost of the best solution found so far, or ``None`` if unavailable."""
50
+ return self._best_cost
51
+
52
+ def _record_best(self, cost: float, best_solution: Any) -> None:
53
+ """Record a new cost value and update the best solution if improved.
54
+
55
+ Parameters
56
+ ----------
57
+ cost : float
58
+ Cost value to be added to the history.
59
+ """
60
+ self._solution_history.append(best_solution)
61
+ self._cost_history.append(cost)
62
+ is_better = (
63
+ self._best_cost is None or
64
+ (self.mode == "min" and cost < self._best_cost) or
65
+ (self.mode == "max" and cost > self._best_cost)
66
+ )
67
+ if is_better:
68
+ self._best_solution = best_solution
69
+ self._best_cost = cost
70
+
71
+ def get_report(self) -> str:
72
+ """Generate a formatted summary report of the optimization process.
73
+
74
+ The report includes the best solution, its associated cost, and the evolution of cost
75
+ values per iteration.
76
+
77
+ Returns
78
+ -------
79
+ report : str
80
+ A formatted string containing the optimization summary.
81
+ """
82
+ if not self._cost_history:
83
+ return "Optimization has not been run. The report is empty."
84
+
85
+ header = "\n" + "=" * 45 + "\n"
86
+ report_parts = [
87
+ header,
88
+ f"{'Optimization Summary':^45}",
89
+ header,
90
+ f"Best cost : {self.best_cost}\n",
91
+ f"Best solution : {self.best_solution}\n",
92
+ "Cost History per Iteration:\n"
93
+ ]
94
+ table_formatter = TableFormatter(
95
+ {
96
+ 'Iteration': 12,
97
+ 'Cost': 28
98
+ }
99
+ )
100
+
101
+ report_parts.extend([table_formatter.get_header()])
102
+
103
+ for i, cost in enumerate(self._cost_history, start=1):
104
+ report_parts.append(
105
+ '\n' + table_formatter.get_row(
106
+ {
107
+ 'Iteration': f"{i:>11} ",
108
+ 'Cost': f"{cost:>27.6f} "
109
+ }
110
+ )
111
+ )
112
+
113
+ report_parts.append(table_formatter.get_bottom(True))
114
+ return "".join(report_parts)
115
+
116
+ @abstractmethod
117
+ def optimize(self, max_iters: int = 50, n_iter_no_change=10, verbose: bool = True) -> Any:
118
+ """Execute the optimization process.
119
+
120
+ This abstract method must be implemented by the subclass, defining
121
+ how the optimization strategy explores the search space.
122
+
123
+ Parameters
124
+ ----------
125
+ max_iters : int
126
+ Maximum number of interactions
127
+ n_iter_no_change: int, default=10
128
+ the maximum number of iterations without updating the best
129
+ verbose : bool, default=True
130
+ Flag to enable or disable detailed output during optimization.
131
+
132
+ Returns
133
+ -------
134
+ best_solution : Any
135
+ The best solution found by the optimization algorithm.
136
+ """
137
+
138
+ @abstractmethod
139
+ def affinity_function(self, solution: Any) -> float:
140
+ """Evaluate the affinity of a candidate solution.
141
+
142
+ This abstract method must be implemented by the subclass to define the problem-specific.
143
+
144
+ Parameters
145
+ ----------
146
+ solution : Any
147
+ Candidate solution to be evaluated.
148
+
149
+ Returns
150
+ -------
151
+ cost : float
152
+ Cost value associated with the given solution.
153
+ """
154
+
155
+ def register(self, alias: str, function: Callable[..., Any]) -> None:
156
+ """Register a function dynamically in the optimizer instance.
157
+
158
+ Parameters
159
+ ----------
160
+ alias : str
161
+ Name used to access the function as an attribute.
162
+ function : Callable[..., Any]
163
+ Callable to be registered.
164
+
165
+ Raises
166
+ ------
167
+ TypeError
168
+ If `function` is not callable.
169
+ AttributeError
170
+ If `alias` is protected and cannot be modified. Or if `alias` does not exist in the
171
+ optimizer class.
172
+ """
173
+ if not callable(function):
174
+ raise TypeError(f"Expected a function for '{alias}', got {type(function).__name__}")
175
+ if alias in self._protected_aliases or alias.startswith("_"):
176
+ raise AttributeError(f"The alias '{alias}' is protected and cannot be modified.")
177
+ if not hasattr(self, alias):
178
+ raise AttributeError(
179
+ f"Alias '{alias}' is not a valid method of {self.__class__.__name__}"
180
+ )
181
+ setattr(self, alias, function)
182
+
183
+ def reset(self):
184
+ """Reset the object's internal state, clearing history and resetting values."""
185
+ self._cost_history: List[float] = []
186
+ self._solution_history: list = []
187
+ self._best_solution: Optional[Any] = None
188
+ self._best_cost: Optional[float] = None
@@ -10,10 +10,11 @@ import numpy.typing as npt
10
10
  from numba import njit, types
11
11
 
12
12
 
13
- @njit([(types.float64[:], types.int64)], cache=True)
13
+ @njit([(types.float64[:], types.int64, types.float64)], cache=True)
14
14
  def clone_and_mutate_continuous(
15
15
  vector: npt.NDArray[np.float64],
16
- n: int
16
+ n: int,
17
+ mutation_rate: float
17
18
  ) -> npt.NDArray[np.float64]:
18
19
  """
19
20
  Generate a set of mutated clones from a cell represented by a continuous vector.
@@ -28,6 +29,10 @@ def clone_and_mutate_continuous(
28
29
  The original immune cell with continuous values to be cloned and mutated.
29
30
  n : int
30
31
  The number of mutated clones to be generated.
32
+ mutation_rate : float, default=1
33
+ If 0 <= mutation_rate < 1: probability of mutating each component.
34
+ If mutation_rate >= 1 or mutation_rate <= 0: the mutation randomizes
35
+ a number of components between 1 and len(vector).
31
36
 
32
37
  Returns
33
38
  -------
@@ -37,12 +42,22 @@ def clone_and_mutate_continuous(
37
42
  n_features = vector.shape[0]
38
43
  clone_set = np.empty((n, n_features), dtype=np.float64)
39
44
  for i in range(n):
40
- n_mutations = np.random.randint(1, n_features)
41
45
  clone = vector.copy()
42
- position_mutations = np.random.permutation(n_features)[:n_mutations]
43
- for j in range(n_mutations):
44
- idx = position_mutations[j]
45
- clone[idx] = np.float64(np.random.random())
46
+ if 0 <= mutation_rate < 1:
47
+ any_mutation = False
48
+ for j in range(n_features):
49
+ if np.random.random() < mutation_rate:
50
+ clone[j] = np.random.random()
51
+ any_mutation = True
52
+ if not any_mutation:
53
+ idx = np.random.randint(0, n_features)
54
+ clone[idx] = np.random.random()
55
+ else:
56
+ n_mutations = np.random.randint(1, n_features)
57
+ position_mutations = np.random.permutation(n_features)[:n_mutations]
58
+ for j in range(n_mutations):
59
+ idx = position_mutations[j]
60
+ clone[idx] = np.float64(np.random.random())
46
61
  clone_set[i] = clone
47
62
 
48
63
  return clone_set
@@ -75,8 +90,8 @@ def clone_and_mutate_binary(
75
90
  n_features = vector.shape[0]
76
91
  clone_set = np.empty((n, n_features), dtype=np.bool_)
77
92
  for i in range(n):
78
- n_mutations = np.random.randint(1, n_features)
79
93
  clone = vector.copy()
94
+ n_mutations = np.random.randint(1, n_features)
80
95
  position_mutations = np.random.permutation(n_features)[:n_mutations]
81
96
  for j in range(n_mutations):
82
97
  idx = position_mutations[j]
@@ -86,11 +101,12 @@ def clone_and_mutate_binary(
86
101
  return clone_set
87
102
 
88
103
 
89
- @njit([(types.float64[:], types.int64, types.float64[:, :])], cache=True)
104
+ @njit([(types.float64[:], types.int64, types.float64[:, :], types.float64)], cache=True)
90
105
  def clone_and_mutate_ranged(
91
106
  vector: npt.NDArray[np.float64],
92
107
  n: int,
93
- bounds: npt.NDArray[np.float64]
108
+ bounds: npt.NDArray[np.float64],
109
+ mutation_rate: float
94
110
  ) -> npt.NDArray[np.float64]:
95
111
  """
96
112
  Generate a set of mutated clones from a cell represented by custom ranges per dimension.
@@ -107,6 +123,10 @@ def clone_and_mutate_ranged(
107
123
  The number of mutated clones to be generated.
108
124
  bounds : np.ndarray
109
125
  Array (n_features, 2) with min and max per dimension.
126
+ mutation_rate : float, default=1
127
+ If 0 <= mutation_rate < 1: probability of mutating each component.
128
+ If mutation_rate >= 1 or mutation_rate <= 0: the mutation randomizes
129
+ a number of components between 1 and len(vector).
110
130
 
111
131
  Returns
112
132
  -------
@@ -117,14 +137,62 @@ def clone_and_mutate_ranged(
117
137
  clone_set = np.empty((n, n_features), dtype=np.float64)
118
138
 
119
139
  for i in range(n):
120
- n_mutations = np.random.randint(1, n_features)
121
140
  clone = vector.copy()
122
- position_mutations = np.random.permutation(n_features)[:n_mutations]
123
- for j in range(n_mutations):
124
- idx = position_mutations[j]
125
- min_limit = bounds[0][idx]
126
- max_limit = bounds[1][idx]
127
- clone[idx] = np.random.uniform(min_limit, max_limit)
141
+ if 0 <= mutation_rate < 1:
142
+ any_mutation = False
143
+ for j in range(n_features):
144
+ if np.random.random() < mutation_rate:
145
+ clone[j] = np.random.uniform(low=bounds[0][j], high=bounds[1][j])
146
+ any_mutation = True
147
+ if not any_mutation:
148
+ idx = np.random.randint(0, n_features)
149
+ clone[idx] = np.random.uniform(low=bounds[0][idx], high=bounds[1][idx])
150
+ else:
151
+ n_mutations = np.random.randint(1, n_features)
152
+ position_mutations = np.random.permutation(n_features)[:n_mutations]
153
+ for j in range(n_mutations):
154
+ idx = position_mutations[j]
155
+ min_limit = bounds[0][idx]
156
+ max_limit = bounds[1][idx]
157
+ clone[idx] = np.random.uniform(low=min_limit, high=max_limit)
158
+ clone_set[i] = clone
159
+
160
+ return clone_set
161
+
162
+
163
+ @njit([(types.int64[:], types.int64, types.float64)], cache=True)
164
+ def clone_and_mutate_permutation(
165
+ vector: npt.NDArray[np.int64],
166
+ n: int,
167
+ mutation_rate: float
168
+ ) -> npt.NDArray[np.int64]:
169
+ """Generate a set of mutated clones by random permutation.
170
+
171
+ Parameters
172
+ ----------
173
+ vector : npt.NDArray[np.int64]
174
+ The original immune cell with permutation values to be cloned and mutated.
175
+ n : int
176
+ The number of mutated clones to be generated.
177
+ mutation_rate : float
178
+ Probability of mutating each component 0 <= mutation_rate < 1.
179
+
180
+ Returns
181
+ -------
182
+ clone_set : npt.NDArray
183
+ An Array(n, len(vector)) containing the `n` mutated clones of the original vector.
184
+ """
185
+ n_features = vector.shape[0]
186
+ clone_set = np.empty((n, n_features), dtype=np.int64)
187
+
188
+ for i in range(n):
189
+ clone = vector.copy()
190
+ for j in range(n_features):
191
+ if np.random.random() < mutation_rate:
192
+ idx = np.random.randint(0, n_features)
193
+ tmp = clone[j]
194
+ clone[j] = clone[idx]
195
+ clone[idx] = tmp
128
196
  clone_set[i] = clone
129
197
 
130
198
  return clone_set
@@ -0,0 +1,49 @@
1
+ """Provide utility functions for generating antibody populations in immunological algorithms."""
2
+
3
+ from typing import Optional
4
+
5
+ import numpy as np
6
+ import numpy.typing as npt
7
+
8
+ from ..utils.types import FeatureTypeAll
9
+
10
+
11
+ def generate_random_antibodies(
12
+ n_samples: int,
13
+ n_features: int,
14
+ feature_type: FeatureTypeAll = "continuous-features",
15
+ bounds: Optional[npt.NDArray[np.float64]] = None
16
+ ) -> npt.NDArray:
17
+ """
18
+ Generate a random antibody population.
19
+
20
+ Parameters
21
+ ----------
22
+ n_samples : int
23
+ Number of antibodies (samples) to generate.
24
+ n_features : int
25
+ Number of features (dimensions) for each antibody.
26
+ feature_type : FeatureType, default="continuous-features"
27
+ Specifies the type of features: "continuous-features", "binary-features",
28
+ "ranged-features", or "permutation-features".
29
+ bounds : np.ndarray
30
+ Array (n_features, 2) with min and max per dimension.
31
+
32
+ Returns
33
+ -------
34
+ npt.NDArray
35
+ Array of shape (n_samples, n_features) containing the generated antibodies.
36
+ """
37
+ if n_features <= 0:
38
+ raise ValueError("Number of features must be greater than zero.")
39
+
40
+ if feature_type == "binary-features":
41
+ return np.random.randint(0, 2, size=(n_samples, n_features)).astype(np.bool_)
42
+ if feature_type == "ranged-features" and bounds is not None:
43
+ return np.random.uniform(low=bounds[0], high=bounds[1], size=(n_samples, n_features))
44
+ if feature_type == "permutation-features":
45
+ return np.array(
46
+ [np.random.permutation(n_features) for _ in range(n_samples)]
47
+ ).astype(dtype=np.int64)
48
+
49
+ return np.random.random_sample(size=(n_samples, n_features))
@@ -0,0 +1,20 @@
1
+ """Module (CSA) Clonal Selection Algorithm.
2
+
3
+ CSAs are inspired by the process of antibody proliferation upon detecting an antigen, during which
4
+ the generated antibodies undergo mutations in an attempt to enhance pathogen recognition.
5
+
6
+ Classes
7
+ -------
8
+ AIRS : Artificial Immune Recognition System.
9
+ A supervised learning algorithm for classification tasks based on the clonal
10
+ selection principle.
11
+ Clonalg : Clonal Selection Algorithm.
12
+ Implementation of the clonal selection algorithm for optimization, adapted
13
+ for both minimization and maximization of cost functions in binary,
14
+ continuous, and permutation problems.
15
+ """
16
+ from ._ai_recognition_sys import AIRS
17
+ from ._clonalg import Clonalg
18
+
19
+ __author__ = 'João Paulo da Silva Barros'
20
+ __all__ = ['AIRS', 'Clonalg']
@@ -53,8 +53,8 @@ class Cell:
53
53
  if feature_type == "binary-features":
54
54
  return clone_and_mutate_binary(self.vector, n)
55
55
  if feature_type == "ranged-features" and bounds is not None:
56
- clone_and_mutate_ranged(self.vector, n, bounds)
57
- return clone_and_mutate_continuous(self.vector, n)
56
+ clone_and_mutate_ranged(self.vector, n, bounds, np.float64(1.0))
57
+ return clone_and_mutate_continuous(self.vector, n, np.float64(1.0))
58
58
 
59
59
  def __eq__(self, other):
60
60
  """Check if two cells are equal."""