fleetmind / src /delivery_dispatch_v3 /seed_catalog.py
Rishav
Refine hard-tier seed calibration
80896fb
Raw
History Blame Contribute Delete
7.24 kB
from __future__ import annotations
import secrets
from .generator import generate_recipe
from .grading import normalize_score, rollout_policy, timed_optimal_reward
from .models import SeedMetadata
from .policies import stay_policy
TRAIN_SEEDS: dict[str, tuple[int, ...]] = {
"v3_easy_dispatch": (143, 129, 111, 147, 155, 131, 107, 141, 151, 119, 139, 123),
"v3_medium_dispatch": (231, 237, 243, 219, 203, 215, 209, 255, 227, 251, 235, 233),
"v3_hard_dispatch": (351, 337, 323, 327, 347, 341, 321, 331, 349, 301, 357, 355),
}
EVAL_SEEDS: dict[str, tuple[int, ...]] = {
"v3_easy_dispatch": (423, 409, 407, 401, 435, 427, 419, 403),
"v3_medium_dispatch": (529, 511, 533, 505, 507, 539, 515, 537),
"v3_hard_dispatch": (601, 635, 639, 619, 617, 607, 611, 613),
}
OFFICIAL_SEEDS: dict[str, tuple[int, ...]] = {
"v3_easy_dispatch": (703, 737, 723, 709),
"v3_medium_dispatch": (819, 837, 807, 827),
"v3_hard_dispatch": (907, 921, 913, 909),
}
TEST_SEEDS: dict[str, tuple[int, ...]] = {
"v3_easy_dispatch": (791, 753, 805, 767, 793, 775, 787, 771, 807, 779, 777, 819, 783, 815, 765, 751),
"v3_medium_dispatch": (875, 857, 879, 867, 859, 849, 851, 893, 887, 843, 871, 885, 847, 855, 873, 863),
"v3_hard_dispatch": (989, 995, 973, 959, 983, 1009, 975, 987, 1005, 945, 979, 997, 1015, 957, 943, 1001),
}
CANDIDATE_SEEDS: dict[str, dict[str, tuple[int, ...]]] = {
"train": {
"v3_easy_dispatch": tuple(range(101, 161, 2)),
"v3_medium_dispatch": tuple(range(201, 261, 2)),
"v3_hard_dispatch": tuple(range(301, 361, 2)),
},
"eval": {
"v3_easy_dispatch": tuple(range(401, 441, 2)),
"v3_medium_dispatch": tuple(range(501, 541, 2)),
"v3_hard_dispatch": tuple(range(601, 641, 2)),
},
"official": {
"v3_easy_dispatch": tuple(range(701, 741, 2)),
"v3_medium_dispatch": tuple(range(801, 841, 2)),
"v3_hard_dispatch": tuple(range(901, 941, 2)),
},
"test": {
"v3_easy_dispatch": tuple(range(741, 821, 2)),
"v3_medium_dispatch": tuple(range(841, 921, 2)),
"v3_hard_dispatch": tuple(range(941, 1021, 2)),
},
}
SEED_POOLS: dict[str, dict[str, tuple[int, ...]]] = {
"train": TRAIN_SEEDS,
"eval": EVAL_SEEDS,
"official": OFFICIAL_SEEDS,
"test": TEST_SEEDS,
}
TASK_IDS: tuple[str, ...] = (
"v3_easy_dispatch",
"v3_medium_dispatch",
"v3_hard_dispatch",
)
def build_seed_metadata(task_id: str, seed: int) -> SeedMetadata:
recipe = generate_recipe(task_id, seed)
baseline_reward = rollout_policy(task_id, seed, policy_name="baseline")
heuristic_reward = rollout_policy(task_id, seed, policy_name="heuristic")
target_reward, runtime_ms = timed_optimal_reward(task_id, seed)
admissible = is_seed_admissible(
target_reward=target_reward,
baseline_reward=baseline_reward,
heuristic_reward=heuristic_reward,
runtime_ms=runtime_ms,
runtime_budget_ms=recipe.profile.runtime_budget_ms,
)
return SeedMetadata(
task_id=task_id,
seed=seed,
world_regime=recipe.world_regime,
hot_zone=recipe.zone_specs[recipe.hot_zone_index].label,
decoy_zone=recipe.zone_specs[recipe.decoy_zone_index].label,
premium_zone=recipe.zone_specs[recipe.premium_zone_index].label,
baseline_reward=baseline_reward,
heuristic_reward=heuristic_reward,
target_reward=target_reward,
score_gap=target_reward - baseline_reward,
heuristic_gap=target_reward - heuristic_reward,
solver_runtime_ms=runtime_ms,
runtime_budget_ms=recipe.profile.runtime_budget_ms,
admissible=admissible,
)
def is_seed_admissible(
target_reward: float,
baseline_reward: float,
heuristic_reward: float,
runtime_ms: float,
runtime_budget_ms: float,
) -> bool:
return (
target_reward - baseline_reward >= 12.0
and target_reward - heuristic_reward >= 8.0
and runtime_ms <= runtime_budget_ms
)
def curate_seed_pool(task_id: str, candidate_seeds: tuple[int, ...], limit: int) -> tuple[int, ...]:
metadatas = [build_seed_metadata(task_id, seed) for seed in candidate_seeds]
admissible = [metadata for metadata in metadatas if metadata.admissible]
if task_id == "v3_hard_dispatch":
hard_rows: list[tuple[SeedMetadata, float, float]] = []
for metadata in admissible:
stay_reward = rollout_episode_with_policy(task_id, metadata.seed, stay_policy)
stay_score = normalize_score(stay_reward, metadata.baseline_reward, metadata.target_reward)
hard_rows.append((metadata, stay_reward, stay_score))
hard_rows = [
row
for row in hard_rows
if (row[0].target_reward - row[1]) >= 18.0 and row[2] <= 0.32
] or hard_rows
hard_rows.sort(
key=lambda row: (
row[0].target_reward - row[1],
row[0].score_gap,
-row[2],
row[0].heuristic_gap,
-row[0].solver_runtime_ms,
),
reverse=True,
)
admissible = [row[0] for row in hard_rows]
else:
admissible.sort(
key=lambda metadata: (
metadata.score_gap,
metadata.heuristic_gap,
-metadata.solver_runtime_ms,
),
reverse=True,
)
chosen: list[int] = []
seen_regimes: set[str] = set()
for metadata in admissible:
if metadata.world_regime not in seen_regimes or len(seen_regimes) >= 4:
chosen.append(metadata.seed)
seen_regimes.add(metadata.world_regime)
if len(chosen) >= limit:
return tuple(chosen)
for metadata in admissible:
if metadata.seed in chosen:
continue
chosen.append(metadata.seed)
if len(chosen) >= limit:
break
return tuple(chosen)
def rollout_episode_with_policy(task_id: str, seed: int, policy) -> float:
from .environment import V3DeliveryDispatchEnv
env = V3DeliveryDispatchEnv(default_task_id=task_id)
observation = env.reset_internal(task_id=task_id, internal_seed=seed)
while not env.done:
result = env.step(policy(observation), grade_terminal=False)
observation = result.observation
return env.cumulative_reward
def resolve_curated_seed(task_id: str, external_seed: int, pool_name: str = "test") -> int:
pool = SEED_POOLS[pool_name][task_id]
if not pool:
raise ValueError(f"No curated seeds for {task_id} in pool '{pool_name}'")
task_offset = sum(ord(character) for character in task_id)
index = ((external_seed * 1315423911) + task_offset) % len(pool)
return pool[index]
def resolve_task_id(external_seed: int) -> str:
return TASK_IDS[external_seed % len(TASK_IDS)]
def choose_random_task_id() -> str:
return secrets.choice(TASK_IDS)
def choose_random_curated_seed(task_id: str, pool_name: str = "test") -> int:
pool = SEED_POOLS[pool_name][task_id]
if not pool:
raise ValueError(f"No curated seeds for {task_id} in pool '{pool_name}'")
return secrets.choice(pool)