Module project.PSO.Particle
Expand source code
from dataclasses import dataclass
import numpy as np
import project.PSO.utils as u
# NOTE need checking when default args are passed during init to enforce
# correctness of values given (they must be inside provided bounds to make
# sense)
@dataclass
class Particle:
"""Representation of multidimensional set of solutions for an
optimization problem. The style of this representation is that
described in the Particle Swarm Optimization heuristic search:
the dimensions of a Particle are encoded as a position in the
search space, which is changed stochastically with the addition
of velocity in the exploration of the search space."""
_dims: dict = None
"""The dimensions of the search space explored in the optimization
problem (they have continuous domain are continuous)"""
position: np.ndarray = None
"""A configuration of values for each of the particle's dimensions
(a vector)"""
pbest_position: np.ndarray = None
"""The particle's fittest configuration of values for the dimensions
of the search space"""
pbest_value: float = -np.inf
"""The particle's fittest configuration of values according to some
evaluation function"""
velocity: np.ndarray = None
"""The particle's velocity (a multidimensional vector), which
stochastically determines the particle's rate of exploration of the
search space. The update formula depends on the particle's inertia, a
cognitive component and a social component
"""
"""Initialize a particle's position and velocity in the search space
randomly, and save best position as current one"""
def __post_init__(self):
self.position = u.distribute_dimensions(self._dims)
self.pbest_position = self.position
self.velocity = u.distribute_dimensions(self._dims, velocity=True)
def __repr__(self) -> str:
return str(self.state)
"""The number of dimensions of this particle"""
@property
def ndim(self) -> int:
return len(self._dims.keys())
"""The identifiers for the dimensions of the search space, as strings"""
@property
def dims(self) -> list:
return list(self._dims.keys())
"""The bounds of the particle's dimensions"""
@property
def dim_bounds(self) -> list:
return list(
map(lambda x: x if isinstance(x, tuple) else (0, len(list(x)) - 1),
self._dims.values()))
"""The representation of all the parameters of the particle as a
dictionary"""
@property
def state(self) -> dict:
return {
"dimensions": {k: v
for k, v in zip(self.dims, self.dim_bounds)},
"position:": self.position,
"pbest_position": self.pbest_position,
"velocity": self.velocity
}
"""Bound the value of a dimension of the particle inside its domain
(the stochastic update may bring it out of bounds)"""
def adjust_position(self):
for idx, bound in enumerate(self.dim_bounds):
low_b, high_b = bound
if self.position[idx] > high_b:
self.position[idx] = high_b
if self.position[idx] < low_b:
self.position[idx] = low_b
"""Update the position of the particle in the search space by
updating its velocity and position"""
def move(self, new_velocity: np.ndarray):
self.velocity = new_velocity
self.position += self.velocity
self.adjust_position()
Classes
class Particle (position: numpy.ndarray = None, pbest_position: numpy.ndarray = None, pbest_value: float = -inf, velocity: numpy.ndarray = None)-
Representation of multidimensional set of solutions for an optimization problem. The style of this representation is that described in the Particle Swarm Optimization heuristic search: the dimensions of a Particle are encoded as a position in the search space, which is changed stochastically with the addition of velocity in the exploration of the search space.
Expand source code
class Particle: """Representation of multidimensional set of solutions for an optimization problem. The style of this representation is that described in the Particle Swarm Optimization heuristic search: the dimensions of a Particle are encoded as a position in the search space, which is changed stochastically with the addition of velocity in the exploration of the search space.""" _dims: dict = None """The dimensions of the search space explored in the optimization problem (they have continuous domain are continuous)""" position: np.ndarray = None """A configuration of values for each of the particle's dimensions (a vector)""" pbest_position: np.ndarray = None """The particle's fittest configuration of values for the dimensions of the search space""" pbest_value: float = -np.inf """The particle's fittest configuration of values according to some evaluation function""" velocity: np.ndarray = None """The particle's velocity (a multidimensional vector), which stochastically determines the particle's rate of exploration of the search space. The update formula depends on the particle's inertia, a cognitive component and a social component """ """Initialize a particle's position and velocity in the search space randomly, and save best position as current one""" def __post_init__(self): self.position = u.distribute_dimensions(self._dims) self.pbest_position = self.position self.velocity = u.distribute_dimensions(self._dims, velocity=True) def __repr__(self) -> str: return str(self.state) """The number of dimensions of this particle""" @property def ndim(self) -> int: return len(self._dims.keys()) """The identifiers for the dimensions of the search space, as strings""" @property def dims(self) -> list: return list(self._dims.keys()) """The bounds of the particle's dimensions""" @property def dim_bounds(self) -> list: return list( map(lambda x: x if isinstance(x, tuple) else (0, len(list(x)) - 1), self._dims.values())) """The representation of all the parameters of the particle as a dictionary""" @property def state(self) -> dict: return { "dimensions": {k: v for k, v in zip(self.dims, self.dim_bounds)}, "position:": self.position, "pbest_position": self.pbest_position, "velocity": self.velocity } """Bound the value of a dimension of the particle inside its domain (the stochastic update may bring it out of bounds)""" def adjust_position(self): for idx, bound in enumerate(self.dim_bounds): low_b, high_b = bound if self.position[idx] > high_b: self.position[idx] = high_b if self.position[idx] < low_b: self.position[idx] = low_b """Update the position of the particle in the search space by updating its velocity and position""" def move(self, new_velocity: np.ndarray): self.velocity = new_velocity self.position += self.velocity self.adjust_position()Class variables
var pbest_position : numpy.ndarray-
The particle's fittest configuration of values for the dimensions of the search space
var pbest_value : float-
The particle's fittest configuration of values according to some evaluation function
var position : numpy.ndarray-
A configuration of values for each of the particle's dimensions (a vector)
var velocity : numpy.ndarray-
The particle's velocity (a multidimensional vector), which stochastically determines the particle's rate of exploration of the search space. The update formula depends on the particle's inertia, a cognitive component and a social component
Instance variables
var dim_bounds : list-
Expand source code
@property def dim_bounds(self) -> list: return list( map(lambda x: x if isinstance(x, tuple) else (0, len(list(x)) - 1), self._dims.values())) var dims : list-
Expand source code
@property def dims(self) -> list: return list(self._dims.keys()) var ndim : int-
Expand source code
@property def ndim(self) -> int: return len(self._dims.keys()) var state : dict-
Expand source code
@property def state(self) -> dict: return { "dimensions": {k: v for k, v in zip(self.dims, self.dim_bounds)}, "position:": self.position, "pbest_position": self.pbest_position, "velocity": self.velocity }
Methods
def adjust_position(self)-
Expand source code
def adjust_position(self): for idx, bound in enumerate(self.dim_bounds): low_b, high_b = bound if self.position[idx] > high_b: self.position[idx] = high_b if self.position[idx] < low_b: self.position[idx] = low_b def move(self, new_velocity: numpy.ndarray)-
Expand source code
def move(self, new_velocity: np.ndarray): self.velocity = new_velocity self.position += self.velocity self.adjust_position()