@File : problem.py @Time : 2024/06/07 14:07:55 @Author : Alejandro Marrero @Version : 1.0 @Contact : amarrerd@ull.edu.es @License : (C)Copyright 2024, Alejandro Marrero @Desc : None

Problem

Bases: ABC, RNG

Source code in digneapy/_core/_problem.py
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
class Problem(ABC, RNG):
    def __init__(
        self,
        dimension: int,
        bounds: Sequence[tuple],
        name: str = "DefaultProblem",
        dtype=np.float64,
        seed: int = 42,
        *args,
        **kwargs,
    ):
        """Creates a new problem instance.
        The problem is defined by its dimension and the bounds of each variable.

        Args:
            dimension (int): Number of variables in the problem
            bounds (Sequence[tuple]): Bounds of each variable in the problem
            name (str, optional): Name of the problem for printing and logging purposes. Defaults to "DefaultProblem".
            dtype (_type_, optional): Type of the variables. Defaults to np.float64.
            seed (int, optional): Seed for the RNG. Defaults to 42.
        """
        self._name = name
        self.__name__ = name
        self._dimension = dimension
        self._bounds = bounds
        self._dtype = dtype
        self.initialize_rng(seed=seed)
        if len(self._bounds) != 0:
            ranges = list(zip(*bounds))
            self._lbs = np.array(ranges[0], dtype=dtype)
            self._ubs = np.array(ranges[1], dtype=dtype)

    @property
    def dimension(self):
        return self._dimension

    @property
    def bounds(self):
        return self._bounds

    def get_bounds_at(self, i: int) -> tuple:
        if i < 0 or i > len(self._bounds):
            raise ValueError(
                f"Index {i} out-of-range. The bounds are 0-{len(self._bounds)} "
            )
        return (self._lbs[i], self._ubs[i])

    @abstractmethod
    def create_solution(self) -> Solution:
        """Creates a random solution to the problem.
        This method can be used to initialise the solutions
        for any algorithm
        """
        msg = "create_solution method not implemented in Problem"
        raise NotImplementedError(msg)

    @abstractmethod
    def evaluate(self, individual: Sequence | Solution) -> Tuple[float]:
        """Evaluates the candidate individual with the information of the Knapsack

        Args:
            individual (Sequence | Solution): Individual to evaluate

        Raises:
            ValueError: Raises an error if the len(individual) != len(instance) / 2

        Returns:
            Tuple[float]: Profit
        """
        msg = "evaluate method not implemented in Problem"
        raise NotImplementedError(msg)

    @abstractmethod
    def __call__(self, individual: Sequence | Solution) -> Tuple[float]:
        msg = "__call__ method not implemented in Problem"
        raise NotImplementedError(msg)

    @abstractmethod
    def to_instance(self) -> Instance:
        """Creates an instance from the information of the problem.
        This method is used in the generators to create instances to evolve
        """
        msg = "to_instance method not implemented in Problem"
        raise NotImplementedError(msg)

    @abstractmethod
    def to_file(self, filename: str):
        msg = "to_file method not implemented in Problem"
        raise NotImplementedError(msg)

    @classmethod
    def from_file(cls, filename: str):
        msg = "from_file method not implemented in Problem"
        raise NotImplementedError(msg)

__init__(dimension, bounds, name='DefaultProblem', dtype=np.float64, seed=42, *args, **kwargs)

Creates a new problem instance. The problem is defined by its dimension and the bounds of each variable.

Parameters:
  • dimension (int) –

    Number of variables in the problem

  • bounds (Sequence[tuple]) –

    Bounds of each variable in the problem

  • name (str, default: 'DefaultProblem' ) –

    Name of the problem for printing and logging purposes. Defaults to "DefaultProblem".

  • dtype (_type_, default: float64 ) –

    Type of the variables. Defaults to np.float64.

  • seed (int, default: 42 ) –

    Seed for the RNG. Defaults to 42.

Source code in digneapy/_core/_problem.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(
    self,
    dimension: int,
    bounds: Sequence[tuple],
    name: str = "DefaultProblem",
    dtype=np.float64,
    seed: int = 42,
    *args,
    **kwargs,
):
    """Creates a new problem instance.
    The problem is defined by its dimension and the bounds of each variable.

    Args:
        dimension (int): Number of variables in the problem
        bounds (Sequence[tuple]): Bounds of each variable in the problem
        name (str, optional): Name of the problem for printing and logging purposes. Defaults to "DefaultProblem".
        dtype (_type_, optional): Type of the variables. Defaults to np.float64.
        seed (int, optional): Seed for the RNG. Defaults to 42.
    """
    self._name = name
    self.__name__ = name
    self._dimension = dimension
    self._bounds = bounds
    self._dtype = dtype
    self.initialize_rng(seed=seed)
    if len(self._bounds) != 0:
        ranges = list(zip(*bounds))
        self._lbs = np.array(ranges[0], dtype=dtype)
        self._ubs = np.array(ranges[1], dtype=dtype)

create_solution() abstractmethod

Creates a random solution to the problem. This method can be used to initialise the solutions for any algorithm

Source code in digneapy/_core/_problem.py
71
72
73
74
75
76
77
78
@abstractmethod
def create_solution(self) -> Solution:
    """Creates a random solution to the problem.
    This method can be used to initialise the solutions
    for any algorithm
    """
    msg = "create_solution method not implemented in Problem"
    raise NotImplementedError(msg)

evaluate(individual) abstractmethod

Evaluates the candidate individual with the information of the Knapsack

Parameters:
  • individual (Sequence | Solution) –

    Individual to evaluate

Raises:
  • ValueError

    Raises an error if the len(individual) != len(instance) / 2

Returns:
  • Tuple[float]

    Tuple[float]: Profit

Source code in digneapy/_core/_problem.py
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
@abstractmethod
def evaluate(self, individual: Sequence | Solution) -> Tuple[float]:
    """Evaluates the candidate individual with the information of the Knapsack

    Args:
        individual (Sequence | Solution): Individual to evaluate

    Raises:
        ValueError: Raises an error if the len(individual) != len(instance) / 2

    Returns:
        Tuple[float]: Profit
    """
    msg = "evaluate method not implemented in Problem"
    raise NotImplementedError(msg)

to_instance() abstractmethod

Creates an instance from the information of the problem. This method is used in the generators to create instances to evolve

Source code in digneapy/_core/_problem.py
101
102
103
104
105
106
107
@abstractmethod
def to_instance(self) -> Instance:
    """Creates an instance from the information of the problem.
    This method is used in the generators to create instances to evolve
    """
    msg = "to_instance method not implemented in Problem"
    raise NotImplementedError(msg)