Coverage for sparkle/platform/output/structures.py: 84%
43 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-07 15:22 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-07 15:22 +0000
1#!/usr/bin/env python3
2"""Sparkle output structures."""
3from __future__ import annotations
4import sys
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."""
17 def __init__(self: ValidationResults, solver: Solver,
18 configuration: dict, instance_set: InstanceSet,
19 results: list[list[str, Status, float, float]]) -> None:
20 """Initalize ValidationResults.
22 Args:
23 solver: The name of the solver
24 configuration: The configuration being used
25 instance_set: The set of instances
26 results: Validation results in the format:
27 [["instance", "status", "quality", "runtime"]]
28 """
29 self.solver = solver
30 self.configuration = configuration
31 self.instance_set = instance_set
32 self.result_header = ["instance", "status", "quality", "runtime"]
33 self.result_vals = results
36class SelectionSolverData:
37 """Class that stores solver information."""
38 def __init__(self: SelectionSolverData,
39 solver_performance_ranking: list[tuple[str, float]],
40 num_solvers: int) -> None:
41 """Initalize SelectionSolverData.
43 Args:
44 solver_performance_ranking: list with solvers ranked by avg. performance
45 num_solvers: The number of solvers
46 """
47 self.solver_performance_ranking = solver_performance_ranking
48 self.single_best_solver = solver_performance_ranking[0][0]
49 self.num_solvers = num_solvers
52class SelectionPerformance:
53 """Class that stores selection performance results."""
54 def __init__(self: SelectionSolverData,
55 performance_path: Path,
56 vbs_performance: float,
57 objective: SparkleObjective) -> None:
58 """Initalize SelectionPerformance.
60 Args:
61 performance_path: Path to portfolio selector performance
62 vbs_performance: The performance of the virtual best selector
63 objective: The objective (Performance type)
64 """
65 if not performance_path.exists():
66 print(f"ERROR: {performance_path} does not exist.")
67 sys.exit(-1)
68 actual_performance_data = PerformanceDataFrame(performance_path)
69 self.vbs_performance = vbs_performance
70 self.actual_performance = actual_performance_data.mean(
71 objective=objective.name)
72 self.metric = objective.name
75class ParallelPortfolioResults:
76 """Class that stores parallel portfolio results."""
77 def __init__(self: ParallelPortfolioResults,
78 unsolved_instances: int,
79 sbs: str,
80 runtime_solvers: dict[str, float],
81 instance_results: dict[str, list]) -> None:
82 """Initalize SelectionSolverData.
84 Args:
85 unsolved_instances: Number of unsolved instances
86 sbs: Name of the single best solver
87 runtime_solvers: Dictionary containing penalised average runtime per solver
88 instance_results: Dictionary containing
89 """
90 self.unsolved_instances = unsolved_instances
91 self.sbs = sbs
92 self.runtime_solvers = runtime_solvers
93 self.instance_results = instance_results
95 self.solver_performance = {}
96 # Iterate over each instance and aggregate the results
97 for _, results in self.instance_results.items():
98 for solver_result in results:
99 solver_name = solver_result[0]
100 outcome = solver_result[1]
101 # Initialize the solver's record in solver_performance if not present
102 if solver_name not in self.solver_performance:
103 self.solver_performance[solver_name] = {
104 status: 0 for status in SolverStatus
105 }
106 # Increment the appropriate outcome count
107 self.solver_performance[solver_name][outcome] += 1