Coverage for o2/actions/legacy_optimos_actions/remove_resource_by_utilization_action.py: 100%

18 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-05-16 11:18 +0000

1from dataclasses import dataclass 

2 

3from o2.actions.base_actions.base_action import RateSelfReturnType 

4from o2.actions.base_actions.modify_resource_base_action import ( 

5 ModifyResourceBaseAction, 

6 ModifyResourceBaseActionParamsType, 

7) 

8from o2.models.solution import Solution 

9from o2.store import Store 

10 

11 

12class RemoveResourceByUtilizationActionParamsType(ModifyResourceBaseActionParamsType): 

13 """Parameter for `RemoveResourceByUtilizationAction`.""" 

14 

15 

16@dataclass(frozen=True) 

17class RemoveResourceByUtilizationAction(ModifyResourceBaseAction, str=False): 

18 """`RemoveResourceByUtilizationAction` will remove the most unutilized resource. 

19 

20 This action is based on the original optimos implementation, 

21 see `resolve_remove_resources_in_process` in that project. 

22 

23 It first gets all resources sorted by their utilization (ascending) 

24 then it removes the resource with the lowest utilization, if that resource's tasks 

25 can be done by other resources. 

26 """ 

27 

28 @staticmethod 

29 def rate_self(store: Store, input: "Solution") -> RateSelfReturnType: 

30 """Generate a best set of parameters & self-evaluates this action.""" 

31 timetable = store.solution.state.timetable 

32 resources = input.evaluation.get_least_utilized_resources() 

33 for resource_id in resources: 

34 resource = timetable.get_resource(resource_id) 

35 if resource is None or not resource.can_safely_be_removed(timetable): 

36 continue 

37 yield ( 

38 RemoveResourceByUtilizationAction.get_default_rating(store), 

39 RemoveResourceByUtilizationAction( 

40 RemoveResourceByUtilizationActionParamsType( 

41 resource_id=resource_id, 

42 remove_resource=True, 

43 ) 

44 ), 

45 ) 

46 

47 return