Coverage for moptipyapps / spoc / spoc_4 / challenge_1 / beginner / objective_no_penalty.py: 61%

31 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-03 04:37 +0000

1""" 

2The objective function of the beginner problem. 

3 

4>>> inst = Instance("matching-i") 

5>>> obj = BeginnerObjectiveNP(inst) 

6 

7>>> test_x = np.ndarray(inst.n, dtype=np.bool) 

8>>> test_x.fill(0) 

9 

10>>> obj.evaluate(test_x) 

110 

12 

13>>> test_x[0] = 1 

14>>> obj.evaluate(test_x) 

15-267 

16>>> inst[0, -1] 

17np.int64(267) 

18 

19The clash of two orbits incurs a penalty: 

20 

21>>> test_x[2234] = 1 

22>>> obj.evaluate(test_x) 

23-7903 

24 

25>>> -267 - 7636 

26-7903 

27""" 

28 

29from typing import Final 

30 

31import numba # type: ignore 

32import numpy as np 

33from moptipy.api.objective import Objective 

34from moptipy.utils.logger import KeyValueLogSection 

35from pycommons.types import type_error 

36 

37from moptipyapps.spoc.spoc_4.challenge_1.beginner.instance import Instance 

38 

39 

40@numba.njit(cache=True, inline="always", fastmath=False, boundscheck=False) 

41def _compute(x: np.ndarray, data: np.ndarray) -> int: 

42 """ 

43 Compute the objective function of the beginner problem. 

44 

45 :param x: the candidate solution 

46 :param data: the orbit data 

47 :return: the objective value, minus the offset 

48 """ 

49 result: int = 0 

50 for i, use in enumerate(x): 

51 if use: 

52 result -= data[i, 3] 

53 return int(result) 

54 

55 

56class BeginnerObjectiveNP(Objective): 

57 """The objective function of the beginner problem.""" 

58 

59 def __init__(self, instance: Instance) -> None: 

60 """ 

61 Create the objective function of the beginner problem. 

62 

63 :param instance: the instance of the objective function. 

64 """ 

65 if not isinstance(instance, Instance): 

66 raise type_error(instance, "instance", Instance) 

67 #: the instance 

68 self.instance: Final[Instance] = instance 

69 

70 def evaluate(self, x) -> int: 

71 """ 

72 Evaluate the objective function of the beginner problem. 

73 

74 :param x: the solution vector 

75 :return: the result 

76 """ 

77 return _compute(x, self.instance) 

78 

79 def lower_bound(self) -> int: 

80 """ 

81 Get the lower bound. 

82 

83 :return: the lower bound 

84 """ 

85 return 1 - self.instance.penalty 

86 

87 def upper_bound(self) -> int: 

88 """ 

89 Get the upper bound. 

90 

91 :return: the upper bound 

92 """ 

93 return 0 

94 

95 def __str__(self) -> str: 

96 """ 

97 Get the name of the objective function. 

98 

99 :return: the name of the objective function 

100 """ 

101 return "spoc4beginnerNP" 

102 

103 def log_parameters_to(self, logger: KeyValueLogSection) -> None: 

104 """ 

105 Log all parameters of this component as key-value pairs. 

106 

107 :param logger: the logger for the parameters 

108 """ 

109 super().log_parameters_to(logger) 

110 with logger.scope("i") as inst: 

111 self.instance.log_parameters_to(inst)