Coverage for sparkle/platform/output/structures.py: 37%

41 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-07-01 13:21 +0000

1#!/usr/bin/env python3 

2"""Sparkle output structures.""" 

3from __future__ import annotations 

4from pathlib import Path 

5 

6from runrunner.base import Status 

7 

8from sparkle.solver import Solver 

9from sparkle.types import SolverStatus, SparkleObjective 

10from sparkle.instance import InstanceSet 

11from sparkle.structures import PerformanceDataFrame 

12 

13 

14class ValidationResults: 

15 """Class that stores validation information and results.""" 

16 def __init__(self: ValidationResults, solver: Solver, 

17 configuration: dict, instance_set: InstanceSet, 

18 results: list[list[str, Status, float, float]]) -> None: 

19 """Initalize ValidationResults. 

20 

21 Args: 

22 solver: The name of the solver 

23 configuration: The configuration being used 

24 instance_set: The set of instances 

25 results: Validation results in the format: 

26 [["instance", "status", "quality", "runtime"]] 

27 """ 

28 self.solver = solver 

29 self.configuration = configuration 

30 self.instance_set = instance_set 

31 self.result_header = ["instance", "status", "quality", "runtime"] 

32 self.result_vals = results 

33 

34 

35class SelectionSolverData: 

36 """Class that stores solver information.""" 

37 def __init__(self: SelectionSolverData, 

38 solver_performance_ranking: list[tuple[str, float]], 

39 num_solvers: int) -> None: 

40 """Initalize SelectionSolverData. 

41 

42 Args: 

43 solver_performance_ranking: list with solvers ranked by avg. performance 

44 num_solvers: The number of solvers 

45 """ 

46 self.solver_performance_ranking = solver_performance_ranking 

47 self.single_best_solver = solver_performance_ranking[0][0] 

48 self.num_solvers = num_solvers 

49 

50 

51class SelectionPerformance: 

52 """Class that stores selection performance results.""" 

53 def __init__(self: SelectionSolverData, 

54 performance_path: Path, 

55 vbs_performance: float, 

56 objective: SparkleObjective) -> None: 

57 """Initalize SelectionPerformance. 

58 

59 Args: 

60 performance_path: Path to portfolio selector performance 

61 vbs_performance: The performance of the virtual best selector 

62 objective: The objective (Performance type) 

63 """ 

64 performance_data = PerformanceDataFrame(performance_path) 

65 from sparkle.selector import SelectionScenario 

66 self.actual_performance_data = performance_data.get_value( 

67 solver=SelectionScenario.__selector_solver_name__, 

68 objective=objective.name) 

69 self.vbs_performance = vbs_performance 

70 self.actual_performance = performance_data.mean(objective=objective.name) 

71 self.metric = objective.name 

72 

73 

74class ParallelPortfolioResults: 

75 """Class that stores parallel portfolio results.""" 

76 def __init__(self: ParallelPortfolioResults, 

77 unsolved_instances: int, 

78 sbs: str, 

79 runtime_solvers: dict[str, float], 

80 instance_results: dict[str, list]) -> None: 

81 """Initalize SelectionSolverData. 

82 

83 Args: 

84 unsolved_instances: Number of unsolved instances 

85 sbs: Name of the single best solver 

86 runtime_solvers: Dictionary containing penalised average runtime per solver 

87 instance_results: Dictionary containing 

88 """ 

89 self.unsolved_instances = unsolved_instances 

90 self.sbs = sbs 

91 self.runtime_solvers = runtime_solvers 

92 self.instance_results = instance_results 

93 

94 self.solver_performance = {} 

95 # Iterate over each instance and aggregate the results 

96 for _, results in self.instance_results.items(): 

97 for solver_result in results: 

98 solver_name = solver_result[0] 

99 outcome = solver_result[1] 

100 # Initialize the solver's record in solver_performance if not present 

101 if solver_name not in self.solver_performance: 

102 self.solver_performance[solver_name] = { 

103 status: 0 for status in SolverStatus 

104 } 

105 # Increment the appropriate outcome count 

106 self.solver_performance[solver_name][outcome] += 1