SabaPivot's picture
download
raw
4 kB
#!/usr/bin/env python
"""Aggregate PDR makespans into relative-to-best gaps (Claim 3 heuristic side).
Reproduces the Table 5 heuristic block:
- per instance: best_observed = min Cmax over the 24-PDR method pool
- relative gap%(method, instance) = Cmax/best_observed - 1 (x100)
- per-method mean gap over the 70 instances
- report best / median / worst heuristic (single fixed rule across instances)
Targets: LIFO+LIT 1.11%, median 1.94%, worst 51.52%.
Also emits per-instance gap vectors for LIFO:LIT and SPT:SPT for the paired
bootstrap CI (bootstrap.py).
"""
from __future__ import annotations
import json
import statistics
from pathlib import Path
ROOT = Path("/home/ubuntu/samuel/dynasched-repro")
MAKESPANS = ROOT / "outputs" / "pdr_makespans.json"
OUT = ROOT / "outputs" / "pdr_gaps.json"
OP_RULES = ["SPT", "LPT", "MWKR", "LWKR", "MOPNR", "LOPNR", "FIFO", "LIFO"]
MACHINE_RULES = ["LIT", "LWL", "SPT"]
RULES = [f"{op}:{mac}" for op in OP_RULES for mac in MACHINE_RULES]
def main():
data = json.loads(MAKESPANS.read_text())
instances = sorted(data.keys())
assert len(instances) == 70, f"expected 70 instances, got {len(instances)}"
for k in instances:
assert set(data[k].keys()) == set(RULES), f"missing rules in {k}"
# per-instance best over the 24-PDR pool
best = {k: min(data[k][r] for r in RULES) for k in instances}
# gap%[rule][instance]
gaps = {r: [] for r in RULES}
gap_by_instance = {k: {} for k in instances}
for k in instances:
for r in RULES:
g = (data[k][r] / best[k] - 1.0) * 100.0
gaps[r].append(g)
gap_by_instance[k][r] = g
# per-method mean gap over 70 instances
mean_gap = {r: statistics.mean(gaps[r]) for r in RULES}
# SE of the mean (for comparison with paper's SE column)
se_gap = {
r: (
statistics.pstdev(gaps[r]) / (len(gaps[r]) ** 0.5)
if len(gaps[r]) > 1
else 0.0
)
for r in RULES
}
# sample-stdev-based SE (paper likely uses sample sd)
se_sample = {r: statistics.stdev(gaps[r]) / (len(gaps[r]) ** 0.5) for r in RULES}
ranked = sorted(RULES, key=lambda r: mean_gap[r])
best_rule = ranked[0]
worst_rule = ranked[-1]
mean_values = sorted(mean_gap[r] for r in RULES)
# median of the per-method mean gaps (across the 24 rules)
median_of_means = statistics.median(mean_values)
print("=== Per-method mean relative-to-best gap (%), 24-PDR pool, 70 instances ===")
for r in ranked:
marker = " <-- LIFO+LIT" if r == "LIFO:LIT" else ""
print(f" {r:10s} mean={mean_gap[r]:7.3f}% SE={se_sample[r]:.4f}{marker}")
print("\n=== Table 5 heuristic block reproduction ===")
print(
f" best heuristic : {best_rule:10s} {mean_gap[best_rule]:.3f}% (target LIFO+LIT 1.11%)"
)
print(f" median (of 24 method means): {median_of_means:.3f}% (target 1.94%)")
print(
f" worst heuristic: {worst_rule:10s} {mean_gap[worst_rule]:.3f}% (target 51.52%)"
)
print(
f" LIFO:LIT mean gap = {mean_gap['LIFO:LIT']:.3f}% SE={se_sample['LIFO:LIT']:.4f} (target 1.11%, SE 0.1540)"
)
print(f" SPT:SPT mean gap = {mean_gap['SPT:SPT']:.3f}%")
out = {
"pool": "24_PDR",
"n_instances": len(instances),
"instances": instances,
"mean_gap_pct": mean_gap,
"se_sample": se_sample,
"ranked_rules": ranked,
"best_rule": best_rule,
"best_mean_gap": mean_gap[best_rule],
"median_of_means": median_of_means,
"worst_rule": worst_rule,
"worst_mean_gap": mean_gap[worst_rule],
"gap_by_instance": gap_by_instance,
"lifo_lit_gap_vector": [gap_by_instance[k]["LIFO:LIT"] for k in instances],
"spt_spt_gap_vector": [gap_by_instance[k]["SPT:SPT"] for k in instances],
}
OUT.write_text(json.dumps(out, indent=2))
print(f"\nWrote {OUT}")
if __name__ == "__main__":
main()

Xet Storage Details

Size:
4 kB
·
Xet hash:
67a0f15651c656c3f1bc3c612f3ff62181426ede51b573f2f92e00608ea7a095

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.