Coverage for sparkle/platform/output/structures.py: 37%
41 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-09-29 10:17 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2025-09-29 10:17 +0000
1#!/usr/bin/env python3
2"""Sparkle output structures."""
4from __future__ import annotations
5from pathlib import Path
7from runrunner.base import Status
9from sparkle.solver import Solver
10from sparkle.types import SolverStatus, SparkleObjective
11from sparkle.instance import InstanceSet
12from sparkle.structures import PerformanceDataFrame
15class ValidationResults:
16 """Class that stores validation information and results."""
18 def __init__(
19 self: ValidationResults,
20 solver: Solver,
21 configuration: dict,
22 instance_set: InstanceSet,
23 results: list[list[str, Status, float, float]],
24 ) -> None:
25 """Initalize ValidationResults.
27 Args:
28 solver: The name of the solver
29 configuration: The configuration being used
30 instance_set: The set of instances
31 results: Validation results in the format:
32 [["instance", "status", "quality", "runtime"]]
33 """
34 self.solver = solver
35 self.configuration = configuration
36 self.instance_set = instance_set
37 self.result_header = ["instance", "status", "quality", "runtime"]
38 self.result_vals = results
41class SelectionSolverData:
42 """Class that stores solver information."""
44 def __init__(
45 self: SelectionSolverData,
46 solver_performance_ranking: list[tuple[str, float]],
47 num_solvers: int,
48 ) -> None:
49 """Initalize SelectionSolverData.
51 Args:
52 solver_performance_ranking: list with solvers ranked by avg. performance
53 num_solvers: The number of solvers
54 """
55 self.solver_performance_ranking = solver_performance_ranking
56 self.single_best_solver = solver_performance_ranking[0][0]
57 self.num_solvers = num_solvers
60class SelectionPerformance:
61 """Class that stores selection performance results."""
63 def __init__(
64 self: SelectionSolverData,
65 performance_path: Path,
66 vbs_performance: float,
67 objective: SparkleObjective,
68 ) -> None:
69 """Initalize SelectionPerformance.
71 Args:
72 performance_path: Path to portfolio selector performance
73 vbs_performance: The performance of the virtual best selector
74 objective: The objective (Performance type)
75 """
76 performance_data = PerformanceDataFrame(performance_path)
77 from sparkle.selector import SelectionScenario
79 self.actual_performance_data = performance_data.get_value(
80 solver=SelectionScenario.__selector_solver_name__, objective=objective.name
81 )
82 self.vbs_performance = vbs_performance
83 self.actual_performance = performance_data.mean(objective=objective.name)
84 self.metric = objective.name
87class ParallelPortfolioResults:
88 """Class that stores parallel portfolio results."""
90 def __init__(
91 self: ParallelPortfolioResults,
92 unsolved_instances: int,
93 sbs: str,
94 runtime_solvers: dict[str, float],
95 instance_results: dict[str, list],
96 ) -> None:
97 """Initalize SelectionSolverData.
99 Args:
100 unsolved_instances: Number of unsolved instances
101 sbs: Name of the single best solver
102 runtime_solvers: Dictionary containing penalised average runtime per solver
103 instance_results: Dictionary containing
104 """
105 self.unsolved_instances = unsolved_instances
106 self.sbs = sbs
107 self.runtime_solvers = runtime_solvers
108 self.instance_results = instance_results
110 self.solver_performance = {}
111 # Iterate over each instance and aggregate the results
112 for _, results in self.instance_results.items():
113 for solver_result in results:
114 solver_name = solver_result[0]
115 outcome = solver_result[1]
116 # Initialize the solver's record in solver_performance if not present
117 if solver_name not in self.solver_performance:
118 self.solver_performance[solver_name] = {
119 status: 0 for status in SolverStatus
120 }
121 # Increment the appropriate outcome count
122 self.solver_performance[solver_name][outcome] += 1