Source code for NiaPy.algorithms.individual

# encoding=utf8

import numpy as np
from numpy import random as rand

from NiaPy.util.utility import objects2array

__all__ = [
    'Individual',
    'defaultNumPyInit',
    'defaultIndividualInit',
]

[docs]class Individual: r"""Class that represents one solution in population of solutions. Date: 2018 Author: Klemen Berkovič License: MIT Attributes: x (numpy.ndarray): Coordinates of individual. f (float): Function/fitness value of individual. """ x = None f = np.inf
[docs] def __init__(self, x=None, task=None, e=True, rnd=rand, **kwargs): r"""Initialize new individual. Parameters: x (Optional[numpy.ndarray]): Individuals components. task (Optional[Task]): Optimization task. e (Optional[bool]): True to evaluate the individual on initialization. Default value is True. rand (Optional[rand.RandomState]): Random generator. **kwargs (Dict[str, Any]): Additional arguments. """ self.f = task.optType.value * np.inf if task is not None else np.inf if x is not None: self.x = x if isinstance(x, np.ndarray) else np.asarray(x) else: self.generateSolution(task, rnd) if e and task is not None: self.evaluate(task, rnd)
[docs] def generateSolution(self, task, rnd=rand): r"""Generate new solution. Generate new solution for this individual and set it to ``self.x``. This method uses ``rnd`` for getting random numbers. For generating random components ``rnd`` and ``task`` is used. Args: task (Task): Optimization task. rnd (Optional[rand.RandomState]): Random numbers generator object. """ if task is not None: self.x = task.Lower + task.bRange * rnd.rand(task.D)
[docs] def evaluate(self, task, rnd=rand): r"""Evaluate the solution. Evaluate solution ``this.x`` with the help of task. Task is used for reparing the solution and then evaluating it. Args: task (Task): Objective function object. rnd (Optional[rand.RandomState]): Random generator. See Also: * :func:`NiaPy.util.Task.repair` """ self.x = task.repair(self.x, rnd=rnd) self.f = task.eval(self.x)
[docs] def copy(self): r"""Return a copy of self. Method returns copy of ``this`` object so it is safe for editing. Returns: Individual: Copy of self. """ return Individual(x=self.x.copy(), f=self.f, e=False)
[docs] def __eq__(self, other): r"""Compare the individuals for equalities. Args: other (Union[Any, np.ndarray]): Object that we want to compare this object to. Returns: bool: `True` if equal or `False` if no equal. """ if isinstance(other, np.ndarray): for e in other: if self == e: return True return False return np.array_equal(self.x, other.x) and self.f == other.f
[docs] def __str__(self): r"""Print the individual with the solution and objective value. Returns: str: String representation of self. """ return '%s -> %s' % (self.x, self.f)
[docs] def __getitem__(self, i): r"""Get the value of i-th component of the solution. Args: i (int): Position of the solution component. Returns: Any: Value of ith component. """ return self.x[i]
[docs] def __setitem__(self, i, v): r"""Set the value of i-th component of the solution to v value. Args: i (int): Position of the solution component. v (Any): Value to set to i-th component. """ self.x[i] = v
[docs] def __len__(self): r"""Get the length of the solution or the number of components. Returns: int: Number of components. """ return len(self.x)
[docs]def defaultNumPyInit(task, NP, rnd=rand, **kwargs): r"""Initialize starting population that is represented with `numpy.ndarray` with shape `{NP, task.D}`. Args: task (Task): Optimization task. NP (int): Number of individuals in population. rnd (Optional[rand.RandomState]): Random number generator. kwargs (Dict[str, Any]): Additional arguments. Returns: Tuple[numpy.ndarray, numpy.ndarray]: 1. New population with shape `{NP, task.D}`. 2. New population function/fitness values. """ pop = task.Lower + rnd.rand(NP, task.D) * task.bRange fpop = np.apply_along_axis(task.eval, 1, pop) return pop, fpop
[docs]def defaultIndividualInit(task, NP, rnd=rand, itype=None, **kwargs): r"""Initialize `NP` individuals of type `itype`. Args: task (Task): Optimization task. NP (int): Number of individuals in population. rnd (Optional[rand.RandomState]): Random number generator. itype (Optional[Individual]): Class of individual in population. kwargs (Dict[str, Any]): Additional arguments. Returns: Tuple[numpy.ndarray, numpy.ndarray]: 1. Initialized individuals. 2. Initialized individuals function/fitness values. """ pop = objects2array([itype(task=task, rnd=rnd, e=True) for _ in range(NP)]) return pop, np.asarray([x.f for x in pop])