"""Báo cáo minh họa bằng dữ liệu giả lập. Điểm nhỏ hơn là tốt hơn.""" from collections import Counter from dataclasses import dataclass from statistics import median @dataclass(frozen=True) class LuotChay: phuong_phap: str instance: str lap: int trang_thai: str hop_le: bool diem: int | None giay_co_nghiem_dau: float | None DU_LIEU_MO_PHONG = [ LuotChay("ASP", "I01", 1, "optimal", True, 10, 1.0), LuotChay("ASP", "I02", 1, "time_limit", True, 18, 5.0), LuotChay("CP", "I01", 1, "optimal", True, 10, 2.0), LuotChay("CP", "I02", 1, "time_limit", False, None, None), LuotChay("SAT/MaxSAT", "I01", 1, "time_limit", True, 12, 2.5), LuotChay("SAT/MaxSAT", "I02", 1, "time_limit", True, 15, 8.0), LuotChay("MIP", "I01", 1, "optimal", True, 10, 1.5), LuotChay("MIP", "I02", 1, "invalid", False, None, None), ] def da_kiem_chung(run): return run.hop_le and run.diem is not None def bao_cao(rows, danh_sach_phuong_phap, ke_hoach): """ke_hoach chứa mọi cặp (instance, lần lặp) đã lên lịch.""" index = {} for run in rows: key = (run.phuong_phap, run.instance, run.lap) if key in index: raise ValueError(f"Trùng lượt chạy: {key}") if run.phuong_phap not in danh_sach_phuong_phap or (run.instance, run.lap) not in ke_hoach: raise ValueError(f"Lượt nằm ngoài kế hoạch: {key}") index[key] = run diem_hop_le = {} for pp in danh_sach_phuong_phap: found = {(i, lap): index[pp, i, lap] for i, lap in ke_hoach if (pp, i, lap) in index} valid = {key: run for key, run in found.items() if da_kiem_chung(run)} times = [run.giay_co_nghiem_dau for run in valid.values() if run.giay_co_nghiem_dau is not None] median_s = median(times) if times else None statuses = dict(sorted(Counter(run.trang_thai for run in found.values()).items())) print(pp, f"lịch hợp lệ {len(valid)}/{len(ke_hoach)}", f"| thiếu log {len(ke_hoach) - len(found)}", "| trung vị giây đến lịch đầu:", median_s, "| trạng thái:", statuses) diem_hop_le[pp] = {key: run.diem for key, run in valid.items()} return diem_hop_le def so_sanh_cap(a, b): common = a.keys() & b.keys() hon = sum(a[key] < b[key] for key in common) bang = sum(a[key] == b[key] for key in common) return len(common), hon, bang, len(common) - hon - bang if __name__ == "__main__": scores = bao_cao(DU_LIEU_MO_PHONG, ["ASP", "CP", "SAT/MaxSAT", "MIP"], {("I01", 1), ("I02", 1)}) result = so_sanh_cap(scores["ASP"], scores["CP"]) print("ASP so với CP (cặp chung, tốt hơn, bằng, kém hơn):", result) assert result == (1, 0, 1, 0) assert so_sanh_cap(scores["ASP"], scores["SAT/MaxSAT"]) == (2, 1, 0, 1)