Coverage for moptipy / examples / jssp / worktime.py: 92%
24 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
1"""Minimize the sum of the work times of all machines in `Gantt` charts."""
2from typing import Final
4import numba # type: ignore
5from pycommons.types import type_error
7from moptipy.api.objective import Objective
8from moptipy.examples.jssp.gantt import Gantt
9from moptipy.examples.jssp.instance import Instance
12@numba.njit(nogil=True, cache=True)
13def worktime(x: Gantt) -> int:
14 """
15 Get the work time of all machines in a given `Gantt` chart.
17 We assume that a machine is turned on when its first job/operation begins
18 and is turned off when the last job/operation on it ends.
19 During all the time inbetween, the machine is on and a worker needs to be
20 present.
21 The work time therefore corresponds to the sum of the time units when the
22 machines can be turned off minus the time units at which they are turned
23 on.
25 :param x: the Gantt chart.
26 :return: the end times minus the start times
27 """
28 return int(x[:, -1, 2].sum()) - int(x[:, 0, 2].sum())
31class Worktime(Objective):
32 """Compute the work time of a `Gantt` chart (for minimization)."""
34 def __init__(self, instance: Instance) -> None: # +book
35 """
36 Initialize the worktime objective function.
38 :param instance: the instance to load the bounds from
39 """
40 super().__init__()
41 if not isinstance(instance, Instance):
42 raise type_error(instance, "instance", Instance)
43 #: the internal instance reference
44 self.__instance: Final[Instance] = instance
45 #: The fast call forwarding to the worktime function. # +book
46 self.evaluate = worktime # type: ignore # +book
48 def lower_bound(self) -> int:
49 """
50 Get the lower bound of the worktime.
52 :return: the lower bound
53 """
54 return self.__instance.makespan_lower_bound \
55 + self.__instance.machines - 1
57 def is_always_integer(self) -> bool:
58 """
59 Return `True` because :func:`worktime` always returns `int` values.
61 :retval True: always
62 """
63 return True
65 def upper_bound(self) -> int:
66 """
67 Get the upper bound of the worktime.
69 :return: the sum of all job execution times.
70 """
71 return self.__instance.makespan_upper_bound * self.__instance.machines
73 def __str__(self) -> str:
74 """
75 Get the name of the worktime objective function.
77 :return: `worktime`
78 :retval "worktime": always
79 """
80 return "worktime"