Coverage for moptipyapps / binpacking2d / objectives / bin_count.py: 96%
24 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 04:40 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 04:40 +0000
1"""
2An objective function for minimizing the number of bins in packings.
4This function returns the number of bins.
5"""
6from typing import Final
8from moptipy.api.objective import Objective
9from pycommons.types import type_error
11from moptipyapps.binpacking2d.instance import Instance
12from moptipyapps.binpacking2d.packing import IDX_BIN
14#: the name of the bin count objective function
15BIN_COUNT_NAME: Final[str] = "binCount"
18class BinCount(Objective):
19 """Compute the number of bins."""
21 def __init__(self, instance: Instance) -> None:
22 """
23 Initialize the number of bins objective function.
25 :param instance: the instance to load the bounds from
26 """
27 super().__init__()
28 if not isinstance(instance, Instance):
29 raise type_error(instance, "instance", Instance)
30 #: the internal instance reference
31 self._instance: Final[Instance] = instance
33 def evaluate(self, x) -> int:
34 """
35 Get the number of bins.
37 :param x: the packing
38 :return: the number of bins used
39 """
40 return int(x[:, IDX_BIN].max())
42 def lower_bound(self) -> int:
43 """
44 Get the lower bound of the number of bins objective.
46 :return: the lower bound for the number of required bins, i.e.,
47 :attr:`~moptipyapps.binpacking2d.instance.Instance.\
48lower_bound_bins`
50 >>> ins = Instance("a", 100, 50, [[10, 5, 1], [3, 3, 1], [5, 5, 1]])
51 >>> ins.lower_bound_bins
52 1
53 >>> BinCount(ins).lower_bound()
54 1
56 >>> ins = Instance("b", 10, 50, [[10, 5, 10], [3, 3, 1], [5, 5, 1]])
57 >>> ins.lower_bound_bins
58 2
59 >>> BinCount(ins).lower_bound()
60 2
62 >>> ins = Instance("c", 10, 50, [[10, 5, 20], [30, 3, 10], [5, 5, 1]])
63 >>> ins.lower_bound_bins
64 4
65 >>> BinCount(ins).lower_bound()
66 4
67 """
68 return self._instance.lower_bound_bins
70 def is_always_integer(self) -> bool:
71 """
72 Return `True` because there are only integer bins.
74 :retval True: always
75 """
76 return True
78 def upper_bound(self) -> int:
79 """
80 Get the upper bound of the number of bins.
82 :return: the number of items in the instance, i.e.,
83 :attr:`~moptipyapps.binpacking2d.instance.Instance.n_items`
85 >>> ins = Instance("a", 100, 50, [[10, 5, 1], [3, 3, 1], [5, 5, 1]])
86 >>> ins.n_items
87 3
88 >>> BinCount(ins).upper_bound()
89 3
91 >>> ins = Instance("b", 10, 50, [[10, 5, 10], [3, 3, 1], [5, 5, 1]])
92 >>> ins.n_items
93 12
94 >>> BinCount(ins).upper_bound()
95 12
97 >>> ins = Instance("c", 10, 50, [[10, 5, 20], [30, 3, 10], [5, 5, 1]])
98 >>> ins.n_items
99 31
100 >>> BinCount(ins).upper_bound()
101 31
102 """
103 return self._instance.n_items
105 def to_bin_count(self, z: int) -> int:
106 """
107 Get the bin count corresponding to an objective value.
109 :param z:
110 :return: the value itself
111 """
112 return z
114 def __str__(self) -> str:
115 """
116 Get the name of the bins objective function.
118 :return: `binCount`
119 :retval "binCount": always
120 """
121 return BIN_COUNT_NAME