Compare commits

..

4 Commits

Author SHA1 Message Date
1096dfa578 feat: Nagercoil single-rider assignment endpoint
Adds POST /api/v1/optimization/nagercoil/riderassign. Nagercoil runs with one
rider, so this skips the matching/VRP/pattern logic in riderassign and straight-
assigns every order to the single rider, then reuses the shared TSP sequencer
(_sync_optimize_route) so stop order, cumulative kms and per-stop ETAs match the
main endpoint's response shape.

Rider defaults to Sivakumar Subramani (userid 852, 8248176099) via the
NAGERCOIL_RIDER constant; a `rider` object in the request body overrides it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018jhRcey2fxhwz2SuPVm7c5
2026-09-03 12:07:17 +05:30
Routes API server
75b175b16f chore: make the deploy directory a real git checkout
/root/Routes-api was not a repository. Work had been done directly here
and existed nowhere else, so deploying from git would have silently
reverted it -- which nearly happened with the Valhalla road-backend
probe. Now the box tracks origin/main, and any drift shows up in
git status instead of being invisible until something breaks.

Runtime state is untracked rather than committed. ml_data holds the live
FAISS delivery-history index and bandit state, and the .pkl files hold
live rider state; all are written by the running container. Tracking
them meant git status was 93 lines of noise that would bury a real source
change, and a stray `git checkout .` would have rolled learned behaviour
back to a months-old commit. They stay on disk, they just leave the index.

Also drops __pycache__ and three stray files (Untitled (2), input,
output) that were committed by accident and no longer exist here.

.env stays tracked but is marked skip-worktree: it is per-environment, so
it would otherwise read as modified forever.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 10:37:47 +00:00
Suriya
4d21b44ddc feat: wire the Doormile endpoint onto the server's actual code
f804791 added app/routes/doormile.py against a base that predated the
Valhalla work. Rebasing it onto 9ef2f61 rewires it to what is really
running, without disturbing anything the server had: the RoadMatrix
probe, road_backend_status and the VALHALLA_URL switch are all intact.

The one thing the endpoint depends on is unchanged --
optimize_provider_payload(orders, start_coords=None) has the same
signature in the server's optimizer as in the version it was written
against -- so passing the kitchen through as the run's start still
works. Tests re-run against the server's code: all pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 15:57:07 +05:30
Suriya
9ef2f61870 sync: capture the production server's code, which was never committed
/root/Routes-api on 31.97.228.132 is not a git repository. Work had been
done directly on the box and existed nowhere else -- a single rm -rf from
being lost, and impossible to review or roll back.

Deploying the previous HEAD over it would have silently reverted all of
this. Most visibly the Valhalla road-backend probe in main.py, whose own
comment explains why it exists: road sequencing degrades to aerial
silently by design, so an unreachable backend stays invisible, "which is
exactly how the expired Google key went unnoticed". Overwriting it would
have reintroduced precisely the failure it was written to catch, and the
service would have kept answering 200 throughout.

The server had also moved from Google Maps to Valhalla for road distance
(VALHALLA_URL, road_backend_status, +190 lines in route_optimizer),
extended docker-compose from 44 to 95 lines, and changed rider fetching,
health, dynamic config and the cache layer.

Only 10 files differ in substance. The other 27 that appeared to differ
were CRLF-vs-LF noise -- the server writes CRLF -- and are normalised to
LF here rather than committed as spurious whole-file rewrites.

Committed as-is, before any change of mine, so the diff that follows is
reviewable against what is actually running.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 15:56:32 +05:30
266 changed files with 590 additions and 50735 deletions

12
.gitignore vendored
View File

@@ -2,3 +2,15 @@ __pycache__/
*.db
*.sqlite3
*.pyc
# Valhalla OSM tiles + extracts (multi-GB, rebuilt from tile_urls)
valhalla_tiles/
# Runtime state written by the container — never source of truth in git.
# ml_data holds the live FAISS delivery-history index and bandit state;
# the .pkl files hold live rider state. Reverting these from git would
# silently reset learned behaviour.
ml_data/
data/
*.pkl
.env.bak-*

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -38,6 +38,9 @@ DEFAULTS: Dict[str, Any] = {
"emergency_load_penalty": 3.0, # km penalty per order in emergency assign
# RouteOptimizer
"search_time_limit_seconds": 5,
# Active-rider roster cache. The upstream getriderlogs call measured ~6s on
# live traffic. Short TTL so on/off-duty changes surface quickly; 0 = off.
"rider_roster_cache_ttl_seconds": 30,
"avg_speed_kmh": 18.0,
"road_factor": 1.3,
# ClusteringService
@@ -56,12 +59,20 @@ DEFAULTS: Dict[str, Any] = {
"eta_history_days": 14, # rolling window pulled from nearledb
"eta_stat": "median", # "median" or "p75" (p75 = more conservative)
"eta_sync_interval_hours": 6, # autonomous background sync cadence
# Road-aware sequencing (Phase 2). OFF by default: enabling adds a Google
# Directions call (cost + latency) to the route hot path. Results are cached.
# Only the *visiting order* changes; step/ETA metrics stay aerial-based.
# Road-aware sequencing (Phase 2). Backed by self-hosted Valhalla, so there is
# no per-request cost — only local latency. Still OFF by default and left to
# the agent to enable on measured gain. Only the *visiting order* changes;
# step/ETA metrics stay aerial-based.
"routing_use_road_distance": False, # AGENT-MANAGED (see routing_auto_manage)
"routing_road_cache_ttl_seconds": 86400, # road geometry is stable; cache 24h
"routing_road_max_stops": 25, # Google distance-matrix practical cap
"routing_road_max_stops": 25, # beyond this the solver time outweighs
# the ordering gain (not a backend cap)
# Valhalla matrix backend. "motorcycle" models the lane access and one-way
# behaviour our riders actually have; "auto" would overstate their travel time.
"routing_valhalla_costing": "motorcycle",
"routing_matrix_timeout_seconds": 15.0,
"routing_matrix_max_unroutable_pct": 20.0, # above this -> tiles likely missing
# this region, fall back to aerial
# Autonomous road-sequencing decision agent: measures road-vs-aerial travel
# time on real batches and flips routing_use_road_distance on its own.
"routing_auto_manage": True, # False -> humans own the flag

View File

@@ -6,7 +6,7 @@ import sys
import time
from contextlib import asynccontextmanager
# Load .env (DB_*, REDIS_*, GOOGLE_MAPS_API_KEY) into the environment early,
# Load .env (DB_*, REDIS_*, VALHALLA_URL) into the environment early,
# before any service reads os.getenv at import time.
try:
from dotenv import load_dotenv
@@ -28,7 +28,7 @@ from app.core.exception_handlers import (
)
from app.core.exceptions import APIException
from app.middleware.request_id import RequestIDMiddleware
from app.routes import cache_router, health_router, ml_router, ml_web_router, optimization_router, batch_analytics_router, riders_router, doormile_router
from app.routes import cache_router, health_router, ml_router, ml_web_router, optimization_router, batch_analytics_router, riders_router, doormile_router, nagercoil_router
# ---------------------------------------------------------------------------
# Logging
@@ -111,6 +111,27 @@ async def lifespan(app: FastAPI):
except Exception as e:
logger.warning(f"[RoadAgent] Decision agent start failed (non-fatal): {e}")
# Probe the Valhalla matrix backend once. Road sequencing degrades to aerial
# silently by design, so without this an unreachable or still-building backend
# stays invisible — which is exactly how the expired Google key went unnoticed.
try:
from app.services.routing.route_optimizer import road_backend_status
_rb = await road_backend_status()
if not _rb.get("configured"):
logger.warning("[RoadMatrix] VALHALLA_URL not set - aerial sequencing only.")
elif _rb.get("reachable"):
logger.info(
f"[RoadMatrix] Valhalla ready at {_rb.get('url')} "
f"(version={_rb.get('version')}, tiles={_rb.get('tileset_last_modified')})"
)
else:
logger.warning(
f"[RoadMatrix] Valhalla at {_rb.get('url')} unreachable "
f"({_rb.get('detail')}) - aerial fallback until it answers."
)
except Exception as e:
logger.warning(f"[RoadMatrix] Backend probe failed (non-fatal): {e}")
logger.info("[OK] Application ready.")
yield
logger.info("[STOP] Route Optimization API shutting down.")
@@ -163,6 +184,7 @@ app.include_router(ml_web_router)
app.include_router(batch_analytics_router)
app.include_router(riders_router)
app.include_router(doormile_router)
app.include_router(nagercoil_router)
@app.get("/", tags=["Root"])

View File

@@ -7,6 +7,7 @@ from .ml_admin import router as ml_router, web_router as ml_web_router
from .batch_analytics import router as batch_analytics_router
from .riders import router as riders_router
from .doormile import router as doormile_router
from .nagercoil import router as nagercoil_router
__all__ = [
"optimization_router",
@@ -17,4 +18,5 @@ __all__ = [
"batch_analytics_router",
"riders_router",
"doormile_router",
"nagercoil_router",
]

View File

@@ -84,6 +84,26 @@ async def readiness_check(request: Request):
}
@router.get("/road-backend")
async def road_backend_check(request: Request):
"""
Status of the Valhalla road-matrix backend used for road-aware stop sequencing.
Deliberately separate from /ready: an unreachable backend is a degradation,
not an outage — routing falls back to aerial ordering and keeps serving. This
endpoint is how you notice the degradation.
"""
from app.services.routing.route_optimizer import road_backend_status
status = await road_backend_status()
return {
**status,
"sequencing_mode": "road" if status.get("reachable") else "aerial",
"timestamp": datetime.utcnow().isoformat() + "Z",
"request_id": getattr(request.state, "request_id", None),
}
@router.get("/live")
async def liveness_check(request: Request):
"""

248
app/routes/nagercoil.py Normal file
View File

@@ -0,0 +1,248 @@
"""Nagercoil single-rider assignment endpoint.
Nagercoil currently operates with exactly one active rider, so the full
matching / VRP / pattern-preassignment machinery in ``riderassign`` is
unnecessary here: every created order goes to that one rider. This endpoint
keeps the same request/response contract as
``POST /api/v1/optimization/riderassign`` but replaces the assignment step
with a straight "all orders → the single rider" hand-off, then reuses the
existing TSP sequencer so the rider still gets an optimised stop order and
per-stop ETAs.
If Nagercoil later grows to more than one rider, switch its caller back to the
main ``riderassign`` endpoint (or add real matching here) — this route
deliberately assumes a single rider and will reject an ambiguous roster.
"""
import asyncio
import logging
import time
from datetime import timedelta
from typing import Any
from fastapi import APIRouter, Body, Query, status
from dateutil.parser import parse as parse_date
# Reuse the exact same sequencer + thread pool the main endpoint uses, so the
# stop ordering and cumulative-km output are identical.
from app.routes.optimization import _sync_optimize_route, _route_executor
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/v1/optimization/nagercoil", tags=["Nagercoil"])
# Nagercoil currently runs with exactly one rider. Every order goes to him
# unless the caller overrides via a `rider` object in the request body.
NAGERCOIL_RIDER = {
"userid": 852,
"username": "Sivakumar Subramani",
"contactno": "8248176099",
}
def _rider_id(r: dict) -> int:
"""Extract a rider's numeric id, tolerating the roster's field variants."""
try:
return int(r.get("userid") or r.get("riderid") or r.get("id") or 0)
except (TypeError, ValueError):
return 0
@router.post(
"/riderassign",
status_code=status.HTTP_200_OK,
summary="Assign all created orders to Nagercoil's single rider",
description="""
Straight-assigns every order to Nagercoil's one active rider, sequences the
stops with the shared TSP optimizer, and returns the same shape as the main
`/api/v1/optimization/riderassign` endpoint.
Rider resolution (first match wins):
1. `rider` object in the body — `{"userid": 555, "username": "...", "contactno": "..."}`
2. otherwise the single active rider returned by the live roster; if the
roster returns zero or more than one rider this endpoint returns a 200
with `status: false` and a message, since Nagercoil is single-rider.
Orders:
- `deliveries` in the body (or a legacy flat list) are used as-is.
- if empty, all `created` orders are fetched from the external API.
""",
responses={
200: {
"content": {
"application/json": {
"example": {
"code": 200,
"details": [{"orderid": "...", "userid": 555, "step": 1}],
"message": "Success",
"status": True,
}
}
}
}
},
)
async def nagercoil_assign(
body: Any = Body(default=None),
reshuffle: bool = Query(False, alias="reshuffle"),
):
from app.services.rider.get_active_riders import fetch_created_orders
from app.services.routing.empirical_eta_calculator import EmpiricalETACalculator
from app.services.routing.realistic_eta_calculator import get_time_of_day_category
eta_calculator = EmpiricalETACalculator()
_t0 = time.time()
try:
# ── Parse payload: {"deliveries": [...], "rider": {...}} or flat list ──
payload_rider = None
if isinstance(body, dict):
payload_rider = body.get("rider") or None
orders = body.get("deliveries") or []
elif isinstance(body, list):
orders = body
else:
orders = []
# ── Resolve the single rider ─────────────────────────────────────────
rider = None
if isinstance(payload_rider, dict) and _rider_id(payload_rider):
rider = payload_rider
if not orders:
orders = await fetch_created_orders()
else:
# No rider in the payload — default to Nagercoil's fixed single rider.
rider = dict(NAGERCOIL_RIDER)
if not orders:
orders = await fetch_created_orders()
rid = _rider_id(rider)
rider_name = rider.get("username", "") or rider.get("name", "")
rider_contact = rider.get("contactno", "")
if not orders:
logger.info("[Nagercoil] No orders to assign.")
return {
"code": 200,
"details": [],
"message": "No created orders to assign.",
"status": True,
"meta": {
"total_orders": 0,
"assigned_orders": 0,
"rider": {"userid": rid, "username": rider_name},
},
}
logger.info(
f"[Nagercoil] Straight-assigning {len(orders)} orders to rider "
f"{rid} ({rider_name})."
)
# ── Sequence the single rider's stops with the shared TSP optimizer ──
loop = asyncio.get_running_loop()
optimized_route = await loop.run_in_executor(
_route_executor, _sync_optimize_route, orders
) or orders # fall back to input order if the optimizer returns nothing
# Total distance for the rider (mirrors riderassign)
try:
total_rider_kms = max(
float(o.get("cumulativekms", 0)) for o in optimized_route
)
except Exception:
total_rider_kms = sum(
float(o.get("actualkms", o.get("kms", 0))) for o in optimized_route
)
# ── Enrich each order exactly like riderassign does ──────────────────
for order in optimized_route:
order["userid"] = rid
order["username"] = rider_name
order["rider"] = rider_name
order["ridercontactno"] = rider_contact
order["riderkms"] = str(round(total_rider_kms, 2))
pickup_slot_str = (
order.get("pickupSlot")
or order.get("pickupslot")
or order.get("pickup_slot")
or order.get("pickuptime")
)
if pickup_slot_str:
try:
pickup_time = parse_date(str(pickup_slot_str))
if order.get("cumulative_eta"):
eta_mins = int(order["cumulative_eta"])
else:
dist_km = float(
order.get("cumulativekms")
or order.get("actualkms", order.get("kms", 0))
)
step = int(order.get("step", 1))
order_type = order.get("ordertype", "Economy")
_dcoords = None
try:
_dlat = float(order.get("deliverylat") or order.get("droplat") or 0)
_dlon = float(order.get("deliverylong") or order.get("droplon") or 0)
if _dlat and _dlon:
_dcoords = (_dlat, _dlon)
except (TypeError, ValueError):
_dcoords = None
eta_mins = eta_calculator.calculate_eta(
distance_km=dist_km,
is_first_order=(step == 1),
order_type=order_type,
time_of_day=get_time_of_day_category(),
kitchen=order.get("pickupcustomer") or order.get("locationname"),
drop_coords=_dcoords,
rider_id=rid,
)
expected_time = pickup_time + timedelta(minutes=eta_mins)
order["expectedDeliveryTime"] = expected_time.strftime(
"%Y-%m-%d %I:%M %p"
)
order["transitMinutes"] = eta_mins
order["calculationDistanceKm"] = round(
float(order.get("cumulativekms") or order.get("actualkms", 0)), 2
)
except Exception as e:
logger.warning(
f"[Nagercoil] ETA calc failed for pickupSlot "
f"'{pickup_slot_str}': {e}"
)
_elapsed_ms = (time.time() - _t0) * 1000.0
logger.info(
f"[API] nagercoil/riderassign ◀ assigned={len(optimized_route)}/"
f"{len(orders)} rider={rid} elapsed={round(_elapsed_ms)}ms"
)
return {
"code": 200,
"details": optimized_route,
"message": "Success",
"status": True,
"meta": {
"total_orders": len(orders),
"assigned_orders": len(optimized_route),
"unassigned_orders": 0,
"rider": {
"userid": rid,
"username": rider_name,
"contactno": rider_contact,
},
"rider_total_kms": round(total_rider_kms, 2),
"reshuffle_mode": reshuffle,
"elapsed_ms": round(_elapsed_ms, 1),
},
}
except Exception as e:
logger.error(f"[Nagercoil] assignment error: {e}", exc_info=True)
return {
"code": 500,
"details": [],
"message": "Internal server error during Nagercoil assignment.",
"status": False,
}

View File

@@ -15,6 +15,31 @@ except Exception: # pragma: no cover
logger = logging.getLogger(__name__)
def _redis_url_from_parts() -> Optional[str]:
"""
Build a redis:// URL from discrete env vars, percent-encoding the credentials.
A hand-written REDIS_URL breaks the moment the password contains a reserved
character: an '@' splits the authority section early, so the client silently
dials a garbage host instead of failing loudly. Assembling the URL here with
quote() removes that whole class of bug - callers set REDIS_HOST/REDIS_PASSWORD
and never have to think about escaping.
Returns None when REDIS_HOST is unset, so an explicit REDIS_URL still wins.
"""
host = os.getenv("REDIS_HOST")
if not host:
return None
from urllib.parse import quote
user = os.getenv("REDIS_USERNAME", "")
pwd = os.getenv("REDIS_PASSWORD", "")
port = os.getenv("REDIS_PORT", "6379")
db = os.getenv("REDIS_DB", "0")
auth = f"{quote(user, safe='')}:{quote(pwd, safe='')}@" if pwd else ""
return f"redis://{auth}{host}:{port}/{db}"
class RedisCache:
"""Lightweight Redis cache wrapper with graceful in-memory fallback."""
@@ -33,9 +58,10 @@ class RedisCache:
self._client = None
self._stats = {"hits": 0, "misses": 0, "sets": 0}
url = os.getenv(url_env)
url = os.getenv(url_env) or _redis_url_from_parts()
if not url or redis is None:
logger.warning("Redis not configured or client unavailable; falling back to local thread-safe in-memory cache")
_why = "redis client not installed" if redis is None else "no REDIS_URL/REDIS_HOST"
logger.warning(f"Redis not configured or client unavailable ({_why}); falling back to local thread-safe in-memory cache")
return
try:
self._client = redis.Redis.from_url(url, decode_responses=True)

View File

@@ -6,13 +6,45 @@ from typing import List, Dict, Any
logger = logging.getLogger(__name__)
def _roster_cache_ttl() -> int:
"""Roster cache TTL in seconds. 0 disables caching entirely."""
try:
from app.config.dynamic_config import get_config
return int(get_config().get("rider_roster_cache_ttl_seconds", 30))
except Exception:
return 30
async def fetch_active_riders() -> List[Dict[str, Any]]:
"""
Fetch active rider logs from the external API for the current date.
Returns a list of rider log dictionaries.
This upstream call measured ~6s on live traffic and was the single largest
component of riderassign latency, so successful responses are cached for
`rider_roster_cache_ttl_seconds`. The TTL is deliberately short: a rider
going on or off duty must become visible quickly, and the absent-rider
validation in the assignment path checks against this roster.
Only non-empty successes are cached. Caching an empty result or a failure
would turn a brief upstream blip into a full-TTL outage where every request
sees zero riders.
"""
today_str = datetime.now().strftime("%Y-%m-%d")
ttl = _roster_cache_ttl()
cache_key = f"riders:active:{today_str}"
if ttl > 0:
try:
from app.services import cache as _cache
cached = _cache.get_json(cache_key)
if isinstance(cached, list) and cached:
logger.debug(f"[Riders] roster cache hit ({len(cached)} riders)")
return cached
except Exception:
pass
try:
today_str = datetime.now().strftime("%Y-%m-%d")
url = "https://jupiter.nearle.app/live/api/v2/partners/getriderlogs/"
params = {
"applocationid": 1,
@@ -32,7 +64,14 @@ async def fetch_active_riders() -> List[Dict[str, Any]]:
# The user's example showed "onduty": 1. We might want to filter by that.
# For now, returning all logs, filtering can happen in assignment logic or here.
# Let's return the raw list as requested, filtering logic will be applied during assignment.
return data.get("details", [])
riders = data.get("details", [])
if riders and ttl > 0:
try:
from app.services import cache as _cache
_cache.set_json(cache_key, riders, ttl_seconds=ttl)
except Exception:
pass
return riders
logger.warning(f"Fetch active riders returned no details: {data}")
return []

View File

@@ -61,8 +61,8 @@ class RoadSequencingAgent:
from app.core.arrow_utils import calculate_haversine_matrix_vectorized
opt = self._optimizer()
if not opt.use_google_maps:
return {"evaluated": 0, "reason": "no_google_key", "mean_gain_pct": 0.0}
if not opt.use_road_matrix:
return {"evaluated": 0, "reason": "no_matrix_backend", "mean_gain_pct": 0.0}
batches = get_delivery_history_service().sample_batches(
days=days, limit=sample_batches

View File

@@ -8,7 +8,7 @@ ALGORITHM: TSP / VRP with Google OR-Tools
FEATURES:
- Automatic outlier detection and coordinate correction
- Hybrid distance calculation (Google Maps + Haversine fallback)
- Hybrid distance calculation (self-hosted Valhalla road matrix + Haversine fallback)
- Robust error handling for invalid inputs
"""
@@ -37,6 +37,37 @@ except ImportError:
logger = logging.getLogger(__name__)
async def road_backend_status() -> Dict[str, Any]:
"""
Probe the Valhalla matrix backend.
Module-level (not a RouteOptimizer method) so startup and health checks can
call it without paying for a full optimizer construction, which pulls in the
empirical ETA calculator and its history load.
"""
url = os.getenv("VALHALLA_URL", "").strip().rstrip("/")
if not url:
return {
"configured": False,
"reachable": False,
"detail": "VALHALLA_URL not set - road sequencing disabled, aerial only",
}
try:
async with httpx.AsyncClient(timeout=5.0) as client:
resp = await client.get(f"{url}/status")
resp.raise_for_status()
data = resp.json()
return {
"configured": True,
"reachable": True,
"url": url,
"version": data.get("version"),
"tileset_last_modified": data.get("tileset_last_modified"),
}
except Exception as e:
return {"configured": True, "reachable": False, "url": url, "detail": str(e)}
class RouteOptimizer:
"""Route optimization using Google OR-Tools (Async)."""
@@ -60,9 +91,11 @@ class RouteOptimizer:
# Road factor (haversine -> road distance multiplier, ML-tuned)
self.road_factor = float(_cfg.get("road_factor"))
# Google Maps API settings
self.google_maps_api_key = os.getenv("GOOGLE_MAPS_API_KEY", "")
self.use_google_maps = bool(self.google_maps_api_key)
# Road travel-time matrix backend: self-hosted Valhalla (no per-request
# cost, no rate limit). Unset VALHALLA_URL -> road sequencing stays off
# and every caller falls back to aerial ordering.
self.valhalla_url = os.getenv("VALHALLA_URL", "").strip().rstrip("/")
self.use_road_matrix = bool(self.valhalla_url)
# Solver time limit (ML-tuned)
self.search_time_limit_seconds = int(_cfg.get("search_time_limit_seconds"))
@@ -90,47 +123,94 @@ class RouteOptimizer:
# ROAD-AWARE VISITING ORDER (Phase 2 - opt-in, cached)
# ------------------------------------------------------------------
def _aerial_minutes(
self, a: Tuple[float, float], b: Tuple[float, float]
) -> float:
"""Haversine travel-time estimate (minutes), used to patch unroutable pairs."""
km = self.haversine_distance(a[0], a[1], b[0], b[1]) * self.road_factor
return (km / (self.avg_speed_kmh or 20.0)) * 60.0
async def _road_duration_matrix(
self, coords: _List[Tuple[float, float]]
) -> Optional[_List[_List[float]]]:
"""
Full NxN road travel-TIME matrix (minutes) via Google Distance Matrix.
Full NxN road travel-TIME matrix (minutes) via self-hosted Valhalla.
One /sources_to_targets call returns the whole matrix, so unlike the old
Google Distance Matrix path there is no per-request element cap and no
chunking. Costing defaults to `motorcycle`, which models the lane access
and one-way behaviour our riders actually have — a car matrix systematically
overstates their travel time.
Valhalla reports an unroutable pair as time=null. Those are patched with an
aerial estimate rather than left at 0, because a 0-cost edge would look
free to the TSP and pull the whole sequence through it. If too many pairs
are unroutable the tileset probably doesn't cover this region, so we bail
to aerial entirely.
Chunks destinations to respect Google's ~100-elements-per-request limit.
Returns None on any failure so the caller falls back to aerial ordering.
"""
if not self.use_google_maps:
if not self.use_road_matrix:
return None
cfg = get_config()
costing = str(cfg.get("routing_valhalla_costing", "motorcycle"))
timeout = float(cfg.get("routing_matrix_timeout_seconds", 15.0))
max_unroutable = float(cfg.get("routing_matrix_max_unroutable_pct", 20.0))
n = len(coords)
origins = "|".join(f"{la},{lo}" for la, lo in coords)
locations = [{"lat": float(la), "lon": float(lo)} for la, lo in coords]
matrix = [[0.0] * n for _ in range(n)]
dest_chunk = max(1, 100 // max(1, n))
try:
async with httpx.AsyncClient(timeout=15.0) as client:
for j0 in range(0, n, dest_chunk):
js = list(range(j0, min(j0 + dest_chunk, n)))
dests = "|".join(f"{coords[j][0]},{coords[j][1]}" for j in js)
resp = await client.get(
"https://maps.googleapis.com/maps/api/distancematrix/json",
params={"origins": origins, "destinations": dests,
"key": self.google_maps_api_key, "units": "metric"},
)
resp.raise_for_status()
data = resp.json()
if data.get("status") != "OK":
logger.debug(f"[RoadSeq] DistanceMatrix status={data.get('status')}")
return None
for i, row in enumerate(data.get("rows", [])):
for k, el in enumerate(row.get("elements", [])):
if el.get("status") == "OK":
dur = el.get("duration", {}).get("value")
if dur is not None:
matrix[i][js[k]] = dur / 60.0
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.post(
f"{self.valhalla_url}/sources_to_targets",
json={
"sources": locations,
"targets": locations,
"costing": costing,
"units": "km",
},
)
resp.raise_for_status()
data = resp.json()
rows = data.get("sources_to_targets") or []
if len(rows) != n:
logger.debug(
f"[RoadSeq] Valhalla returned {len(rows)} rows, expected {n}"
)
return None
unroutable = 0
for i, row in enumerate(rows):
for el in row or []:
j = el.get("to_index")
if j is None or not (0 <= j < n):
continue
secs = el.get("time")
if secs is None:
unroutable += 1
matrix[i][j] = self._aerial_minutes(coords[i], coords[j])
else:
matrix[i][j] = secs / 60.0
pct = 100.0 * unroutable / max(1, n * n)
if pct > max_unroutable:
logger.warning(
f"[RoadSeq] {unroutable}/{n * n} pairs ({pct:.0f}%) unroutable via "
f"Valhalla - tileset likely missing this region; using aerial"
)
return None
if unroutable:
logger.debug(
f"[RoadSeq] patched {unroutable}/{n * n} unroutable pairs with aerial"
)
return matrix
except Exception as e:
logger.debug(f"[RoadSeq] matrix build failed: {e}")
return None
async def _road_optimal_order(
self,
start_lat: float,
@@ -140,27 +220,25 @@ class RouteOptimizer:
"""
Road-aware visiting order for `points`, starting from (start_lat, start_lon).
Builds a real road travel-TIME matrix (Google Distance Matrix) and solves
an OPEN TSP with OR-Tools (return-to-depot edge = 0), so the sequence
respects real road geometry/one-ways instead of straight-line distance.
Validated on live batches to cut real travel time ~5-13% vs aerial; note
Google's Directions optimize:true is NOT used - it optimises a closed loop
and measured *worse* than aerial for our open delivery routes.
Builds a real road travel-TIME matrix (Valhalla) and solves an OPEN TSP
with OR-Tools (return-to-depot edge = 0), so the sequence respects real
road geometry/one-ways instead of straight-line distance. Validated on
live batches to cut real travel time ~5-13% vs aerial.
Returns 0-based indices into `points` in optimal order, or None to signal
the caller to fall back to the existing aerial greedy + 2-opt.
Safe + cheap on the live path:
* disabled unless `routing_use_road_distance` AND a Google key is set
Safe on the live path:
* disabled unless `routing_use_road_distance` AND VALHALLA_URL is set
* only for 3..`routing_road_max_stops` stops (fewer is trivial; more
exceeds Google's waypoint-optimize cap)
costs more solver time than the ordering gain is worth)
* result cached in Redis (default 24h) keyed by the rounded coords in
input order, so the returned indices always map back correctly
"""
cfg = get_config()
if not cfg.get("routing_use_road_distance", False):
return None
if not self.use_google_maps:
if not self.use_road_matrix:
return None
n = len(points)
if n < 3 or n > int(cfg.get("routing_road_max_stops", 25)):
@@ -362,14 +440,17 @@ class RouteOptimizer:
search_params.local_search_metaheuristic = (
routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
)
# TSP time limit hard-capped at 2 seconds per kitchen.
# search_time_limit_seconds can be tuned up to 8-10s via config, but at
# delivery scale (< 15 stops)
# OR-Tools finds a near-optimal solution in < 200ms. Waiting 8-10s
# per kitchen x 3 kitchens x 4 riders = 96s of unnecessary waiting.
# The VRP already has its own 3s cap. This cap applies to per-rider
# TSP and the per-kitchen beatmap solves.
search_params.time_limit.seconds = min(self.search_time_limit_seconds, 2)
# TSP time budget, ceiling 2 seconds per kitchen. This cap applies to
# per-rider TSP and the per-kitchen beatmap solves.
#
# GUIDED_LOCAL_SEARCH runs until its time limit EXPIRES - it does not
# return early once it has the optimum. A flat cap therefore burned the
# whole budget on trivial inputs, where PATH_CHEAPEST_ARC is done in
# under 200ms. Scale with stop count; large inputs still get the ceiling.
_cap_ms = min(self.search_time_limit_seconds, 2) * 1000
search_params.time_limit.FromMilliseconds(
max(200, min(_cap_ms, 200 * len(locations)))
)
solution = routing.SolveWithParameters(search_params)
@@ -742,13 +823,18 @@ class RouteOptimizer:
sp.local_search_metaheuristic = (
routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
)
# VRP time budget: cap at 3 seconds so the API response is never
# VRP time budget: ceiling of 3 seconds so the API response is never
# blocked longer than that. The x 3 multiplier caused 15-second
# responses with the default 5-second search_time_limit.
# PATH_CHEAPEST_ARC typically finds a good solution in < 1 second
# for our typical sizes (<= 15 riders, <= 60 orders); GLS then
# improves it within the remaining budget.
sp.time_limit.seconds = min(self.search_time_limit_seconds, 3)
#
# GUIDED_LOCAL_SEARCH runs until its time limit EXPIRES rather than
# stopping once the optimum is found, so a flat 3s spent ~2.9s of
# pure waiting on a 1-order batch (measured on live traffic).
# Scale with problem size; large batches still get the full ceiling.
_cap_ms = min(self.search_time_limit_seconds, 3) * 1000
sp.time_limit.FromMilliseconds(
max(250, min(_cap_ms, 250 * len(orders)))
)
solution = routing.SolveWithParameters(sp)

View File

@@ -1 +0,0 @@
<EFBFBD>}<7D>.

Binary file not shown.

View File

@@ -3,6 +3,9 @@ version: "3.9"
networks:
frontend:
external: true
# redis + postgres-logistics live here; routes_api joins it purely to reach redis.
logistics:
external: true
services:
routes_api:
@@ -14,13 +17,20 @@ services:
restart: unless-stopped
environment:
- UVICORN_WORKERS=2
- REDIS_URL=redis://:${REDIS_PASSWORD}@routes_redis:6379/0
# Redis as discrete parts, NOT a hand-built REDIS_URL: the password contains
# reserved characters and inlining it produced redis://:pa@ss@routes_redis/...,
# which resolved to a garbage host and silently fell back to in-memory cache.
# app/services/__init__.py percent-encodes these when assembling the URL.
# Host is `redis` (its container name) on the logistics network.
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD}
# Optional: Set cache TTL in seconds (default: 300 = 5 min, 86400 = 24h)
# Uncomment and set in .env file: REDIS_CACHE_TTL_SECONDS=86400
# - REDIS_CACHE_TTL_SECONDS=${REDIS_CACHE_TTL_SECONDS}
# Google Maps API key for accurate road distance calculation (actualkms)
# Set in .env file: GOOGLE_MAPS_API_KEY=your_api_key_here
- GOOGLE_MAPS_API_KEY=${GOOGLE_MAPS_API_KEY}
# Self-hosted Valhalla, source of the road travel-time matrix used for
# road-aware stop sequencing. Unset -> sequencing falls back to aerial.
- VALHALLA_URL=http://routes_valhalla:8002
# nearledb (read-only) — source for empirical ETA learning
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
@@ -42,3 +52,44 @@ services:
- ./delivery_corrections.csv:/app/delivery_corrections.csv:ro
networks:
- frontend
- logistics
# Road travel-time matrix backend. Replaces the Google Distance Matrix API:
# no key, no per-request cost, no element cap, and a real `motorcycle` costing
# model instead of car durations.
#
# Deliberately NOT using tile_urls. This host has 3.8 GB RAM and runs production
# alongside it; building the 556 MB South India extract here risks the OOM killer
# taking down routes_api/postgres. Instead ./valhalla_tiles holds a pre-clipped
# Coimbatore PBF (bbox 76.60,10.70 -> 77.30,11.35, derived from the actual
# delivery coordinates in delivery_details.csv, which span only ~19 km). Valhalla
# builds from any .pbf it finds in /custom_files.
#
# To re-clip after an OSM refresh, on the host:
# osmium extract -b 76.60,10.70,77.30,11.35 <southern-zone>.osm.pbf \
# -o valhalla_tiles/coimbatore.osm.pbf
# docker compose up -d --force-recreate valhalla # with force_rebuild=True
valhalla:
image: ghcr.io/valhalla/valhalla-scripted:latest
container_name: routes_valhalla
restart: unless-stopped
environment:
- serve_tiles=True
- force_rebuild=False
- build_elevation=False
# India drives on the left; admin regions are what teach Valhalla that.
- build_admins=True
- build_time_zones=True
# Reuse built tiles on restart instead of rebuilding from the PBF.
- use_tiles_ignore_pbf=True
# Hard cap so a runaway tile build gets killed instead of the OOM killer
# picking off production containers on this 3.8 GB host.
mem_limit: 2g
volumes:
- ./valhalla_tiles:/custom_files
# Loopback-only: the API reaches Valhalla over the docker network, so this
# is purely for local probing. Valhalla has no auth — do not bind 0.0.0.0.
ports:
- "127.0.0.1:8002:8002"
networks:
- frontend

3554
input

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
{
"source": "db",
"csv_mtime": 0,
"record_count": 4348,
"pattern_zones": 192,
"clear_patterns": 145
}

View File

@@ -1,7 +0,0 @@
{
"source": "csv",
"csv_mtime": 1779805148.3161151,
"record_count": 3610,
"pattern_zones": 173,
"clear_patterns": 127
}

View File

@@ -1,193 +0,0 @@
{
"timestamp": "2026-04-06T10:13:05.823653",
"training_rows": 42,
"n_trials": 150,
"best_predicted_quality": 74.73,
"best_params": {
"max_pickup_distance_km": 7.314920981190028,
"max_kitchen_distance_km": 4.8848250212533415,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.5921999872066053,
"workload_penalty_weight": 169.06315001171424,
"distance_penalty_weight": 1.1915857216557537,
"cluster_radius_km": 3.558231774658527,
"search_time_limit_seconds": 9,
"road_factor": 1.3099009557863963
},
"validation": {
"r2_score": 0.5681,
"mae": 8.266,
"folds": 5,
"trust_level": "acceptable",
"trust_score": 2,
"interpretation": "Predictions off by +/-8.3 pts (R2=0.57, trust=acceptable)"
},
"baseline_stats": {
"avg_quality": 57.09,
"best_quality": 94.11,
"worst_quality": 30.0,
"sample_size": 42
},
"feature_importance": {
"rolling_avg_quality_5": 38.71,
"quality_delta_10": 20.33,
"num_orders": 19.03,
"hour": 13.32,
"num_riders": 7.86,
"day_of_week": 0.75
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 7.314920981190028,
"max_kitchen_distance_km": 4.8848250212533415,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.5921999872066053,
"workload_penalty_weight": 169.06315001171424,
"distance_penalty_weight": 1.1915857216557537,
"cluster_radius_km": 3.558231774658527,
"search_time_limit_seconds": 9,
"road_factor": 1.3099009557863963
},
"score": 74.7316665649414
},
{
"params": {
"max_pickup_distance_km": 7.237104762434787,
"max_kitchen_distance_km": 7.550474896953535,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.5890554510417833,
"workload_penalty_weight": 185.96752993783272,
"distance_penalty_weight": 1.31602349600973,
"cluster_radius_km": 3.8526888873500074,
"search_time_limit_seconds": 9,
"road_factor": 1.319424296170459
},
"score": 74.7316665649414
},
{
"params": {
"max_pickup_distance_km": 7.436288448216707,
"max_kitchen_distance_km": 4.919546048309047,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.591148300459874,
"workload_penalty_weight": 168.30230726961742,
"distance_penalty_weight": 1.2493078409207465,
"cluster_radius_km": 3.556472953280938,
"search_time_limit_seconds": 9,
"road_factor": 1.3302725639166417
},
"score": 74.7316665649414
},
{
"params": {
"max_pickup_distance_km": 7.325529314582726,
"max_kitchen_distance_km": 4.649587629606767,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.590873440986851,
"workload_penalty_weight": 168.438723345984,
"distance_penalty_weight": 1.1422464826358736,
"cluster_radius_km": 3.849796402096792,
"search_time_limit_seconds": 9,
"road_factor": 1.3098146276588136
},
"score": 74.7316665649414
},
{
"params": {
"max_pickup_distance_km": 7.280718743288656,
"max_kitchen_distance_km": 4.619748595285139,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.5876942359983096,
"workload_penalty_weight": 175.5427402190054,
"distance_penalty_weight": 1.234091340676156,
"cluster_radius_km": 3.596367136362332,
"search_time_limit_seconds": 9,
"road_factor": 1.3269755250627069
},
"score": 74.7316665649414
},
{
"params": {
"max_pickup_distance_km": 7.492629035525449,
"max_kitchen_distance_km": 4.249165472314659,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.6002837964896123,
"workload_penalty_weight": 173.37495123965752,
"distance_penalty_weight": 1.1908166833096747,
"cluster_radius_km": 3.543115179563585,
"search_time_limit_seconds": 9,
"road_factor": 1.3281385493416102
},
"score": 74.7316665649414
},
{
"params": {
"max_pickup_distance_km": 7.171116733882171,
"max_kitchen_distance_km": 4.315631232490625,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.5943191618773355,
"workload_penalty_weight": 167.9049180092559,
"distance_penalty_weight": 1.173862334055753,
"cluster_radius_km": 3.596417271778823,
"search_time_limit_seconds": 9,
"road_factor": 1.310786907921741
},
"score": 74.7316665649414
},
{
"params": {
"max_pickup_distance_km": 7.398947077752536,
"max_kitchen_distance_km": 4.573012985025286,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.588382785737964,
"workload_penalty_weight": 171.56836325664975,
"distance_penalty_weight": 1.2420650483510813,
"cluster_radius_km": 3.821463414056532,
"search_time_limit_seconds": 9,
"road_factor": 1.3094083355796955
},
"score": 74.7316665649414
},
{
"params": {
"max_pickup_distance_km": 7.413205466370695,
"max_kitchen_distance_km": 4.882557712376696,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.5938285091458789,
"workload_penalty_weight": 169.18170748664954,
"distance_penalty_weight": 1.2065256426925077,
"cluster_radius_km": 3.567236434547114,
"search_time_limit_seconds": 9,
"road_factor": 1.3261515305765197
},
"score": 74.7316665649414
},
{
"params": {
"max_pickup_distance_km": 7.321140036068694,
"max_kitchen_distance_km": 4.591113450191565,
"max_orders_per_rider": 17,
"ideal_load": 6,
"workload_balance_threshold": 0.595465392809937,
"workload_penalty_weight": 168.84486091695908,
"distance_penalty_weight": 1.1874534780471975,
"cluster_radius_km": 3.5809336353167915,
"search_time_limit_seconds": 9,
"road_factor": 1.3136308854673249
},
"score": 74.7316665649414
}
],
"pareto_frontier": []
}

View File

@@ -1,195 +0,0 @@
{
"timestamp": "2026-04-06T11:15:21.558462",
"training_rows": 46,
"n_trials": 100,
"best_predicted_quality": 86.11,
"best_params": {
"max_pickup_distance_km": 6.392662787995912,
"max_kitchen_distance_km": 4.190289209141789,
"max_orders_per_rider": 16,
"ideal_load": 6,
"workload_balance_threshold": 0.5872426915922554,
"workload_penalty_weight": 159.52479411472802,
"distance_penalty_weight": 1.3976431795210602,
"cluster_radius_km": 3.8669714076918487,
"search_time_limit_seconds": 10,
"road_factor": 1.351027788721731
},
"validation": {
"r2_score": 0.6054,
"mae": 7.772,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-7.8 pts (R2=0.61, trust=good)"
},
"baseline_stats": {
"avg_quality": 60.17,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 46
},
"feature_importance": {
"rolling_avg_quality_5": 37.57,
"quality_delta_10": 20.49,
"num_orders": 19.39,
"hour": 14.34,
"num_riders": 7.31,
"day_of_week": 0.7,
"max_pickup_distance_km": 0.11,
"max_kitchen_distance_km": 0.09
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.392662787995912,
"max_kitchen_distance_km": 4.190289209141789,
"max_orders_per_rider": 16,
"ideal_load": 6,
"workload_balance_threshold": 0.5872426915922554,
"workload_penalty_weight": 159.52479411472802,
"distance_penalty_weight": 1.3976431795210602,
"cluster_radius_km": 3.8669714076918487,
"search_time_limit_seconds": 10,
"road_factor": 1.351027788721731
},
"score": 86.11234283447266
},
{
"params": {
"max_pickup_distance_km": 6.297815963257037,
"max_kitchen_distance_km": 3.8505754898634783,
"max_orders_per_rider": 16,
"ideal_load": 6,
"workload_balance_threshold": 0.5777296561934621,
"workload_penalty_weight": 158.4868458705779,
"distance_penalty_weight": 1.1423080241802208,
"cluster_radius_km": 3.8767987765353027,
"search_time_limit_seconds": 10,
"road_factor": 1.3590795828321593
},
"score": 86.11234283447266
},
{
"params": {
"max_pickup_distance_km": 5.755525935494492,
"max_kitchen_distance_km": 3.602878250833593,
"max_orders_per_rider": 16,
"ideal_load": 6,
"workload_balance_threshold": 0.5810550224170309,
"workload_penalty_weight": 158.33102695144956,
"distance_penalty_weight": 0.8359797517849566,
"cluster_radius_km": 4.070265749604756,
"search_time_limit_seconds": 11,
"road_factor": 1.3679995251023478
},
"score": 86.11234283447266
},
{
"params": {
"max_pickup_distance_km": 5.668048149252538,
"max_kitchen_distance_km": 3.757664730583838,
"max_orders_per_rider": 15,
"ideal_load": 6,
"workload_balance_threshold": 0.5760811821610472,
"workload_penalty_weight": 151.63492791057107,
"distance_penalty_weight": 0.5702726198142655,
"cluster_radius_km": 4.072347742407765,
"search_time_limit_seconds": 10,
"road_factor": 1.3745093953873153
},
"score": 86.11234283447266
},
{
"params": {
"max_pickup_distance_km": 6.234799364645242,
"max_kitchen_distance_km": 3.608238936343494,
"max_orders_per_rider": 16,
"ideal_load": 6,
"workload_balance_threshold": 0.5751866568653705,
"workload_penalty_weight": 157.49526762895485,
"distance_penalty_weight": 0.6684963010048837,
"cluster_radius_km": 4.563846747791826,
"search_time_limit_seconds": 10,
"road_factor": 1.3851224149782055
},
"score": 86.11234283447266
},
{
"params": {
"max_pickup_distance_km": 5.778552719231634,
"max_kitchen_distance_km": 3.985822473534986,
"max_orders_per_rider": 15,
"ideal_load": 6,
"workload_balance_threshold": 0.5421608115737091,
"workload_penalty_weight": 152.2200014192961,
"distance_penalty_weight": 0.5061267867737343,
"cluster_radius_km": 4.504093235986498,
"search_time_limit_seconds": 11,
"road_factor": 1.3752847449065841
},
"score": 86.11234283447266
},
{
"params": {
"max_pickup_distance_km": 5.544498941283227,
"max_kitchen_distance_km": 3.526639801749269,
"max_orders_per_rider": 15,
"ideal_load": 6,
"workload_balance_threshold": 0.5366736949070521,
"workload_penalty_weight": 143.0095516901684,
"distance_penalty_weight": 0.576086222260539,
"cluster_radius_km": 4.650857718738661,
"search_time_limit_seconds": 11,
"road_factor": 1.4022032523207215
},
"score": 86.11234283447266
},
{
"params": {
"max_pickup_distance_km": 5.834348418882515,
"max_kitchen_distance_km": 3.727707528717965,
"max_orders_per_rider": 15,
"ideal_load": 6,
"workload_balance_threshold": 0.5313909879772015,
"workload_penalty_weight": 146.66435736231995,
"distance_penalty_weight": 0.5890932671599473,
"cluster_radius_km": 4.566568289844027,
"search_time_limit_seconds": 11,
"road_factor": 1.3767549301227895
},
"score": 86.11234283447266
},
{
"params": {
"max_pickup_distance_km": 5.887294356657819,
"max_kitchen_distance_km": 3.446156802802312,
"max_orders_per_rider": 15,
"ideal_load": 6,
"workload_balance_threshold": 0.4956698206614236,
"workload_penalty_weight": 145.08886239416043,
"distance_penalty_weight": 0.5619044128499937,
"cluster_radius_km": 4.741476812566594,
"search_time_limit_seconds": 11,
"road_factor": 1.3958241864702816
},
"score": 86.11234283447266
},
{
"params": {
"max_pickup_distance_km": 5.7337206831750684,
"max_kitchen_distance_km": 3.448896621982922,
"max_orders_per_rider": 16,
"ideal_load": 6,
"workload_balance_threshold": 0.5305940896716139,
"workload_penalty_weight": 145.6036252229628,
"distance_penalty_weight": 0.5686017128719028,
"cluster_radius_km": 4.581905382792808,
"search_time_limit_seconds": 11,
"road_factor": 1.3816713599748103
},
"score": 86.11234283447266
}
],
"pareto_frontier": []
}

View File

@@ -1,195 +0,0 @@
{
"timestamp": "2026-04-06T11:27:05.547790",
"training_rows": 56,
"n_trials": 100,
"best_predicted_quality": 86.86,
"best_params": {
"max_pickup_distance_km": 5.754228294857152,
"max_kitchen_distance_km": 3.5401397044432863,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5303258275965647,
"workload_penalty_weight": 148.2974521657742,
"distance_penalty_weight": 0.8448126470984346,
"cluster_radius_km": 5.116539293876776,
"search_time_limit_seconds": 11,
"road_factor": 1.400897182838108
},
"validation": {
"r2_score": 0.7062,
"mae": 6.737,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-6.7 pts (R2=0.71, trust=good)"
},
"baseline_stats": {
"avg_quality": 65.28,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 56
},
"feature_importance": {
"rolling_avg_quality_5": 36.88,
"quality_delta_10": 21.26,
"num_orders": 19.48,
"hour": 14.46,
"num_riders": 6.75,
"day_of_week": 0.65,
"max_pickup_distance_km": 0.36,
"max_kitchen_distance_km": 0.17
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 5.754228294857152,
"max_kitchen_distance_km": 3.5401397044432863,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5303258275965647,
"workload_penalty_weight": 148.2974521657742,
"distance_penalty_weight": 0.8448126470984346,
"cluster_radius_km": 5.116539293876776,
"search_time_limit_seconds": 11,
"road_factor": 1.400897182838108
},
"score": 86.86381530761719
},
{
"params": {
"max_pickup_distance_km": 5.9946340351245615,
"max_kitchen_distance_km": 3.5718829801604155,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.531860400747863,
"workload_penalty_weight": 156.33441133773653,
"distance_penalty_weight": 0.8685997952158602,
"cluster_radius_km": 5.198614116122955,
"search_time_limit_seconds": 12,
"road_factor": 1.4018892215050491
},
"score": 86.86381530761719
},
{
"params": {
"max_pickup_distance_km": 6.105258536422472,
"max_kitchen_distance_km": 3.6976829030462475,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5388030619730716,
"workload_penalty_weight": 157.01841824594652,
"distance_penalty_weight": 0.8722055219643643,
"cluster_radius_km": 5.255269567532107,
"search_time_limit_seconds": 13,
"road_factor": 1.4187048027518931
},
"score": 86.86381530761719
},
{
"params": {
"max_pickup_distance_km": 6.1086693731841635,
"max_kitchen_distance_km": 3.8697437187246932,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5386198223243897,
"workload_penalty_weight": 155.03608813276117,
"distance_penalty_weight": 0.9008859330224005,
"cluster_radius_km": 5.394163081995417,
"search_time_limit_seconds": 13,
"road_factor": 1.4236552114446452
},
"score": 86.86381530761719
},
{
"params": {
"max_pickup_distance_km": 6.128213089295225,
"max_kitchen_distance_km": 3.849163463086135,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5441620345096512,
"workload_penalty_weight": 156.83172650936578,
"distance_penalty_weight": 0.8871558854958876,
"cluster_radius_km": 5.073434533857966,
"search_time_limit_seconds": 13,
"road_factor": 1.435827692627751
},
"score": 86.86381530761719
},
{
"params": {
"max_pickup_distance_km": 6.340483581316396,
"max_kitchen_distance_km": 3.9034377978970274,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5442832933506564,
"workload_penalty_weight": 154.74461044822505,
"distance_penalty_weight": 0.8860393814330001,
"cluster_radius_km": 5.423331802727045,
"search_time_limit_seconds": 13,
"road_factor": 1.4320444686252563
},
"score": 86.86381530761719
},
{
"params": {
"max_pickup_distance_km": 6.354116300119992,
"max_kitchen_distance_km": 3.8842834181273576,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5437101399226733,
"workload_penalty_weight": 156.68291617578234,
"distance_penalty_weight": 0.8795681893638614,
"cluster_radius_km": 5.428404376648247,
"search_time_limit_seconds": 13,
"road_factor": 1.4529085299702669
},
"score": 86.86381530761719
},
{
"params": {
"max_pickup_distance_km": 6.351668559299965,
"max_kitchen_distance_km": 3.863707133424694,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5440550956654271,
"workload_penalty_weight": 156.93143052929284,
"distance_penalty_weight": 0.8888601449255451,
"cluster_radius_km": 5.485806856584574,
"search_time_limit_seconds": 13,
"road_factor": 1.430060874518316
},
"score": 86.86381530761719
},
{
"params": {
"max_pickup_distance_km": 6.36340684056692,
"max_kitchen_distance_km": 3.8544747047074113,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5477473200120031,
"workload_penalty_weight": 156.75808775095646,
"distance_penalty_weight": 0.9210789943267018,
"cluster_radius_km": 5.660715379307142,
"search_time_limit_seconds": 13,
"road_factor": 1.4449700025276115
},
"score": 86.86381530761719
},
{
"params": {
"max_pickup_distance_km": 6.337201751606118,
"max_kitchen_distance_km": 3.9155047746745466,
"max_orders_per_rider": 16,
"ideal_load": 5,
"workload_balance_threshold": 0.5460757043805732,
"workload_penalty_weight": 157.44456134140316,
"distance_penalty_weight": 0.8990546723563242,
"cluster_radius_km": 5.452152416986682,
"search_time_limit_seconds": 13,
"road_factor": 1.4450395913087812
},
"score": 86.86381530761719
}
],
"pareto_frontier": []
}

View File

@@ -1,197 +0,0 @@
{
"timestamp": "2026-04-06T11:34:20.840607",
"training_rows": 57,
"n_trials": 150,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.741,
"mae": 6.313,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-6.3 pts (R2=0.74, trust=good)"
},
"baseline_stats": {
"avg_quality": 65.71,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 57
},
"feature_importance": {
"rolling_avg_quality_5": 36.34,
"quality_delta_10": 21.91,
"num_orders": 19.6,
"hour": 14.36,
"num_riders": 6.2,
"max_pickup_distance_km": 0.69,
"day_of_week": 0.59,
"max_kitchen_distance_km": 0.24,
"workload_balance_threshold": 0.07,
"distance_penalty_weight": 0.02
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,201 +0,0 @@
{
"timestamp": "2026-04-07T01:59:38.951100",
"training_rows": 67,
"n_trials": 100,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.7524,
"mae": 5.994,
"folds": 5,
"trust_level": "strong",
"trust_score": 4,
"interpretation": "Predictions off by +/-6.0 pts (R2=0.75, trust=strong)"
},
"baseline_stats": {
"avg_quality": 67.97,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 67
},
"feature_importance": {
"rolling_avg_quality_5": 35.23,
"quality_delta_10": 22.24,
"num_orders": 19.32,
"hour": 14.27,
"num_riders": 5.97,
"max_pickup_distance_km": 1.1,
"day_of_week": 0.86,
"ideal_load": 0.38,
"max_kitchen_distance_km": 0.29,
"workload_balance_threshold": 0.2,
"distance_penalty_weight": 0.08,
"max_orders_per_rider": 0.03,
"search_time_limit_seconds": 0.03,
"is_peak": 0.02
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,201 +0,0 @@
{
"timestamp": "2026-04-07T04:44:22.624847",
"training_rows": 70,
"n_trials": 150,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.7574,
"mae": 5.954,
"folds": 5,
"trust_level": "strong",
"trust_score": 4,
"interpretation": "Predictions off by +/-6.0 pts (R2=0.76, trust=strong)"
},
"baseline_stats": {
"avg_quality": 68.57,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 70
},
"feature_importance": {
"rolling_avg_quality_5": 34.94,
"quality_delta_10": 21.89,
"num_orders": 17.3,
"hour": 10.45,
"num_riders": 7.5,
"day_of_week": 2.97,
"max_pickup_distance_km": 2.95,
"max_kitchen_distance_km": 1.16,
"max_orders_per_rider": 0.23,
"workload_penalty_weight": 0.21,
"ideal_load": 0.14,
"distance_penalty_weight": 0.14,
"workload_balance_threshold": 0.07,
"is_peak": 0.05
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,201 +0,0 @@
{
"timestamp": "2026-04-07T05:34:06.339200",
"training_rows": 70,
"n_trials": 150,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.7574,
"mae": 5.954,
"folds": 5,
"trust_level": "strong",
"trust_score": 4,
"interpretation": "Predictions off by +/-6.0 pts (R2=0.76, trust=strong)"
},
"baseline_stats": {
"avg_quality": 68.57,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 70
},
"feature_importance": {
"rolling_avg_quality_5": 34.58,
"quality_delta_10": 22.11,
"num_orders": 18.73,
"hour": 14.0,
"num_riders": 6.28,
"max_pickup_distance_km": 1.43,
"day_of_week": 1.24,
"ideal_load": 0.61,
"max_kitchen_distance_km": 0.5,
"workload_balance_threshold": 0.26,
"distance_penalty_weight": 0.12,
"max_orders_per_rider": 0.05,
"is_peak": 0.04,
"search_time_limit_seconds": 0.04
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,202 +0,0 @@
{
"timestamp": "2026-04-07T05:50:38.347689",
"training_rows": 77,
"n_trials": 100,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.7538,
"mae": 6.159,
"folds": 5,
"trust_level": "strong",
"trust_score": 4,
"interpretation": "Predictions off by +/-6.2 pts (R2=0.75, trust=strong)"
},
"baseline_stats": {
"avg_quality": 67.8,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 77
},
"feature_importance": {
"rolling_avg_quality_5": 33.69,
"quality_delta_10": 22.59,
"num_orders": 18.35,
"hour": 13.78,
"num_riders": 6.32,
"day_of_week": 1.86,
"max_pickup_distance_km": 1.42,
"ideal_load": 0.79,
"max_kitchen_distance_km": 0.61,
"workload_balance_threshold": 0.26,
"distance_penalty_weight": 0.16,
"max_orders_per_rider": 0.05,
"search_time_limit_seconds": 0.05,
"is_peak": 0.04,
"workload_penalty_weight": 0.04
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,202 +0,0 @@
{
"timestamp": "2026-04-07T05:55:20.028939",
"training_rows": 79,
"n_trials": 150,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.7895,
"mae": 5.74,
"folds": 5,
"trust_level": "strong",
"trust_score": 4,
"interpretation": "Predictions off by +/-5.7 pts (R2=0.79, trust=strong)"
},
"baseline_stats": {
"avg_quality": 67.25,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 79
},
"feature_importance": {
"rolling_avg_quality_5": 33.16,
"quality_delta_10": 23.13,
"num_orders": 17.92,
"hour": 13.47,
"num_riders": 6.38,
"day_of_week": 2.31,
"max_pickup_distance_km": 1.46,
"ideal_load": 0.92,
"max_kitchen_distance_km": 0.62,
"workload_balance_threshold": 0.28,
"distance_penalty_weight": 0.16,
"is_peak": 0.06,
"max_orders_per_rider": 0.04,
"workload_penalty_weight": 0.04,
"search_time_limit_seconds": 0.04
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-07T06:12:51.914811",
"training_rows": 89,
"n_trials": 100,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.6857,
"mae": 7.752,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-7.8 pts (R2=0.69, trust=good)"
},
"baseline_stats": {
"avg_quality": 66.45,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 89
},
"feature_importance": {
"rolling_avg_quality_5": 32.79,
"quality_delta_10": 23.41,
"num_orders": 18.02,
"hour": 13.23,
"num_riders": 6.32,
"day_of_week": 2.58,
"max_pickup_distance_km": 1.47,
"ideal_load": 0.89,
"max_kitchen_distance_km": 0.65,
"workload_balance_threshold": 0.28,
"distance_penalty_weight": 0.15,
"is_peak": 0.05,
"max_orders_per_rider": 0.05,
"workload_penalty_weight": 0.05,
"search_time_limit_seconds": 0.04,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-07T07:26:54.875923",
"training_rows": 97,
"n_trials": 150,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.7088,
"mae": 6.684,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-6.7 pts (R2=0.71, trust=good)"
},
"baseline_stats": {
"avg_quality": 68.32,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 97
},
"feature_importance": {
"rolling_avg_quality_5": 32.52,
"quality_delta_10": 23.45,
"num_orders": 17.89,
"hour": 13.29,
"num_riders": 6.31,
"day_of_week": 2.86,
"max_pickup_distance_km": 1.51,
"ideal_load": 0.87,
"max_kitchen_distance_km": 0.69,
"workload_balance_threshold": 0.26,
"distance_penalty_weight": 0.15,
"workload_penalty_weight": 0.06,
"is_peak": 0.05,
"max_orders_per_rider": 0.05,
"search_time_limit_seconds": 0.04,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-07T07:30:36.399076",
"training_rows": 97,
"n_trials": 150,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.7088,
"mae": 6.684,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-6.7 pts (R2=0.71, trust=good)"
},
"baseline_stats": {
"avg_quality": 68.32,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 97
},
"feature_importance": {
"rolling_avg_quality_5": 32.37,
"quality_delta_10": 23.52,
"num_orders": 17.69,
"hour": 13.16,
"num_riders": 6.24,
"day_of_week": 3.27,
"max_pickup_distance_km": 1.52,
"ideal_load": 0.88,
"max_kitchen_distance_km": 0.74,
"workload_balance_threshold": 0.26,
"distance_penalty_weight": 0.15,
"workload_penalty_weight": 0.06,
"is_peak": 0.05,
"max_orders_per_rider": 0.04,
"search_time_limit_seconds": 0.04,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-07T08:38:37.380580",
"training_rows": 97,
"n_trials": 150,
"best_predicted_quality": 89.24,
"best_params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"validation": {
"r2_score": 0.7088,
"mae": 6.684,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-6.7 pts (R2=0.71, trust=good)"
},
"baseline_stats": {
"avg_quality": 68.32,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 97
},
"feature_importance": {
"rolling_avg_quality_5": 32.5,
"quality_delta_10": 23.4,
"num_orders": 17.57,
"hour": 12.99,
"num_riders": 6.14,
"day_of_week": 3.61,
"max_pickup_distance_km": 1.56,
"ideal_load": 0.89,
"max_kitchen_distance_km": 0.75,
"workload_balance_threshold": 0.26,
"distance_penalty_weight": 0.15,
"workload_penalty_weight": 0.06,
"is_peak": 0.05,
"max_orders_per_rider": 0.04,
"search_time_limit_seconds": 0.03,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 6.735532343839225,
"max_kitchen_distance_km": 4.197619251759459,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.5214245551586657,
"workload_penalty_weight": 163.0140787394627,
"distance_penalty_weight": 1.3934513637108987,
"cluster_radius_km": 5.037360156635181,
"search_time_limit_seconds": 12,
"road_factor": 1.5171200156937537
},
"score": 89.23719024658203
},
{
"params": {
"max_pickup_distance_km": 6.841710404740362,
"max_kitchen_distance_km": 4.198812185585421,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8052332485018651,
"workload_penalty_weight": 165.15689218876625,
"distance_penalty_weight": 1.4435780491881305,
"cluster_radius_km": 5.072181010489,
"search_time_limit_seconds": 12,
"road_factor": 1.5088037965000476
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.820924491481588,
"max_kitchen_distance_km": 4.2236188681147215,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9412844641881769,
"workload_penalty_weight": 164.41212568224842,
"distance_penalty_weight": 1.80390299391351,
"cluster_radius_km": 5.068709178325149,
"search_time_limit_seconds": 12,
"road_factor": 1.5114592113174095
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.771003849233631,
"max_kitchen_distance_km": 4.260033470051556,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9419209792018807,
"workload_penalty_weight": 163.16077813565002,
"distance_penalty_weight": 2.009287785194642,
"cluster_radius_km": 5.059599874516481,
"search_time_limit_seconds": 12,
"road_factor": 1.510934727861319
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.865086023552823,
"max_kitchen_distance_km": 4.2300955001234835,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9485099501223543,
"workload_penalty_weight": 113.50121305628458,
"distance_penalty_weight": 2.217076259867863,
"cluster_radius_km": 5.0206807120073345,
"search_time_limit_seconds": 12,
"road_factor": 1.5158307797044195
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.809685584778185,
"max_kitchen_distance_km": 4.2054614892522615,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9498351517670537,
"workload_penalty_weight": 121.30396082659882,
"distance_penalty_weight": 2.3357136947778963,
"cluster_radius_km": 5.0512215296804115,
"search_time_limit_seconds": 12,
"road_factor": 1.5116252292771089
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.813005359405248,
"max_kitchen_distance_km": 4.1953195698102,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9408856743556727,
"workload_penalty_weight": 112.5369693779748,
"distance_penalty_weight": 2.2557510241755763,
"cluster_radius_km": 5.072844374062231,
"search_time_limit_seconds": 12,
"road_factor": 1.5122502590292002
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.804074242310791,
"max_kitchen_distance_km": 4.206409080848127,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9468038885349329,
"workload_penalty_weight": 118.93403357911558,
"distance_penalty_weight": 2.2764083947813107,
"cluster_radius_km": 5.044194353666736,
"search_time_limit_seconds": 12,
"road_factor": 1.5146413175465638
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.83707314646065,
"max_kitchen_distance_km": 4.23929386242376,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9453355580279756,
"workload_penalty_weight": 116.37037778507518,
"distance_penalty_weight": 2.4693040098737296,
"cluster_radius_km": 5.072886824671098,
"search_time_limit_seconds": 12,
"road_factor": 1.5159033836084548
},
"score": 89.02847290039062
},
{
"params": {
"max_pickup_distance_km": 6.830306126015477,
"max_kitchen_distance_km": 4.217592923048695,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.9455786388966734,
"workload_penalty_weight": 114.0384093899957,
"distance_penalty_weight": 2.2458270153688256,
"cluster_radius_km": 5.072205045478337,
"search_time_limit_seconds": 12,
"road_factor": 1.5099991858145683
},
"score": 89.02847290039062
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-07T10:03:05.667921",
"training_rows": 97,
"n_trials": 150,
"best_predicted_quality": 89.4,
"best_params": {
"max_pickup_distance_km": 7.130020162334684,
"max_kitchen_distance_km": 4.280839128384073,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8854582632265207,
"workload_penalty_weight": 105.43303608103864,
"distance_penalty_weight": 2.3152400473443335,
"cluster_radius_km": 4.722786290266237,
"search_time_limit_seconds": 13,
"road_factor": 1.5274307417515143
},
"validation": {
"r2_score": 0.7088,
"mae": 6.684,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-6.7 pts (R2=0.71, trust=good)"
},
"baseline_stats": {
"avg_quality": 68.32,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 97
},
"feature_importance": {
"rolling_avg_quality_5": 32.72,
"quality_delta_10": 23.53,
"num_orders": 17.26,
"hour": 12.84,
"num_riders": 6.04,
"day_of_week": 3.81,
"max_pickup_distance_km": 1.59,
"ideal_load": 0.85,
"max_kitchen_distance_km": 0.73,
"workload_balance_threshold": 0.27,
"distance_penalty_weight": 0.15,
"workload_penalty_weight": 0.07,
"is_peak": 0.05,
"search_time_limit_seconds": 0.05,
"max_orders_per_rider": 0.04,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 7.130020162334684,
"max_kitchen_distance_km": 4.280839128384073,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8854582632265207,
"workload_penalty_weight": 105.43303608103864,
"distance_penalty_weight": 2.3152400473443335,
"cluster_radius_km": 4.722786290266237,
"search_time_limit_seconds": 13,
"road_factor": 1.5274307417515143
},
"score": 89.39888000488281
},
{
"params": {
"max_pickup_distance_km": 7.159371587069677,
"max_kitchen_distance_km": 4.033386033322248,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.863536050890365,
"workload_penalty_weight": 97.43265762258073,
"distance_penalty_weight": 1.9100499560802082,
"cluster_radius_km": 4.511755856356149,
"search_time_limit_seconds": 14,
"road_factor": 1.4939199795886327
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.237839336535851,
"max_kitchen_distance_km": 3.663365702556132,
"max_orders_per_rider": 16,
"ideal_load": 4,
"workload_balance_threshold": 0.8735336296938158,
"workload_penalty_weight": 87.18895234690117,
"distance_penalty_weight": 1.902615724431142,
"cluster_radius_km": 4.135522505489794,
"search_time_limit_seconds": 14,
"road_factor": 1.4941578228086358
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.209008794453106,
"max_kitchen_distance_km": 3.5871901473162935,
"max_orders_per_rider": 17,
"ideal_load": 4,
"workload_balance_threshold": 0.8636601075743638,
"workload_penalty_weight": 86.88314997861353,
"distance_penalty_weight": 1.713990617922939,
"cluster_radius_km": 3.9805610734693078,
"search_time_limit_seconds": 14,
"road_factor": 1.4709255743019745
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.293606340881382,
"max_kitchen_distance_km": 3.6099841904143544,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8391162982772516,
"workload_penalty_weight": 81.78402384933284,
"distance_penalty_weight": 1.4924949118149284,
"cluster_radius_km": 4.004081091262425,
"search_time_limit_seconds": 15,
"road_factor": 1.4950180193418494
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.231818308493086,
"max_kitchen_distance_km": 3.5987025683885814,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8679819345591729,
"workload_penalty_weight": 84.66571137735836,
"distance_penalty_weight": 1.7142915230680047,
"cluster_radius_km": 3.9216203223089767,
"search_time_limit_seconds": 14,
"road_factor": 1.4831054798161563
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.300424964430984,
"max_kitchen_distance_km": 3.6131608968543274,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8475063079023154,
"workload_penalty_weight": 84.06676343906496,
"distance_penalty_weight": 1.5413441475020342,
"cluster_radius_km": 3.911615413718933,
"search_time_limit_seconds": 14,
"road_factor": 1.4812141284424145
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.265650750564059,
"max_kitchen_distance_km": 3.590986817226879,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8536491441751559,
"workload_penalty_weight": 83.53289668387433,
"distance_penalty_weight": 1.529774802118949,
"cluster_radius_km": 3.572233786654972,
"search_time_limit_seconds": 15,
"road_factor": 1.485395954896316
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.263343465055543,
"max_kitchen_distance_km": 3.7746106852600296,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8456925598017999,
"workload_penalty_weight": 86.05760075611829,
"distance_penalty_weight": 1.5496670626377171,
"cluster_radius_km": 3.4692879161186077,
"search_time_limit_seconds": 15,
"road_factor": 1.4938443091991387
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.225549460912673,
"max_kitchen_distance_km": 3.546815323022868,
"max_orders_per_rider": 17,
"ideal_load": 2,
"workload_balance_threshold": 0.8538034239262067,
"workload_penalty_weight": 79.43517045634971,
"distance_penalty_weight": 1.3116923117558434,
"cluster_radius_km": 3.88979206962715,
"search_time_limit_seconds": 14,
"road_factor": 1.4911856069021672
},
"score": 89.29891967773438
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-07T11:03:53.039644",
"training_rows": 100,
"n_trials": 100,
"best_predicted_quality": 89.4,
"best_params": {
"max_pickup_distance_km": 7.130020162334684,
"max_kitchen_distance_km": 4.280839128384073,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8854582632265207,
"workload_penalty_weight": 105.43303608103864,
"distance_penalty_weight": 2.3152400473443335,
"cluster_radius_km": 4.722786290266237,
"search_time_limit_seconds": 13,
"road_factor": 1.5274307417515143
},
"validation": {
"r2_score": 0.6699,
"mae": 7.393,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-7.4 pts (R2=0.67, trust=good)"
},
"baseline_stats": {
"avg_quality": 68.97,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 100
},
"feature_importance": {
"rolling_avg_quality_5": 32.86,
"quality_delta_10": 23.57,
"num_orders": 17.08,
"hour": 12.54,
"num_riders": 5.97,
"day_of_week": 3.87,
"max_pickup_distance_km": 1.6,
"ideal_load": 0.84,
"max_kitchen_distance_km": 0.7,
"workload_balance_threshold": 0.56,
"distance_penalty_weight": 0.2,
"workload_penalty_weight": 0.07,
"search_time_limit_seconds": 0.07,
"is_peak": 0.04,
"max_orders_per_rider": 0.04,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 7.130020162334684,
"max_kitchen_distance_km": 4.280839128384073,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8854582632265207,
"workload_penalty_weight": 105.43303608103864,
"distance_penalty_weight": 2.3152400473443335,
"cluster_radius_km": 4.722786290266237,
"search_time_limit_seconds": 13,
"road_factor": 1.5274307417515143
},
"score": 89.39888000488281
},
{
"params": {
"max_pickup_distance_km": 7.159371587069677,
"max_kitchen_distance_km": 4.033386033322248,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.863536050890365,
"workload_penalty_weight": 97.43265762258073,
"distance_penalty_weight": 1.9100499560802082,
"cluster_radius_km": 4.511755856356149,
"search_time_limit_seconds": 14,
"road_factor": 1.4939199795886327
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.237839336535851,
"max_kitchen_distance_km": 3.663365702556132,
"max_orders_per_rider": 16,
"ideal_load": 4,
"workload_balance_threshold": 0.8735336296938158,
"workload_penalty_weight": 87.18895234690117,
"distance_penalty_weight": 1.902615724431142,
"cluster_radius_km": 4.135522505489794,
"search_time_limit_seconds": 14,
"road_factor": 1.4941578228086358
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.209008794453106,
"max_kitchen_distance_km": 3.5871901473162935,
"max_orders_per_rider": 17,
"ideal_load": 4,
"workload_balance_threshold": 0.8636601075743638,
"workload_penalty_weight": 86.88314997861353,
"distance_penalty_weight": 1.713990617922939,
"cluster_radius_km": 3.9805610734693078,
"search_time_limit_seconds": 14,
"road_factor": 1.4709255743019745
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.293606340881382,
"max_kitchen_distance_km": 3.6099841904143544,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8391162982772516,
"workload_penalty_weight": 81.78402384933284,
"distance_penalty_weight": 1.4924949118149284,
"cluster_radius_km": 4.004081091262425,
"search_time_limit_seconds": 15,
"road_factor": 1.4950180193418494
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.231818308493086,
"max_kitchen_distance_km": 3.5987025683885814,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8679819345591729,
"workload_penalty_weight": 84.66571137735836,
"distance_penalty_weight": 1.7142915230680047,
"cluster_radius_km": 3.9216203223089767,
"search_time_limit_seconds": 14,
"road_factor": 1.4831054798161563
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.300424964430984,
"max_kitchen_distance_km": 3.6131608968543274,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8475063079023154,
"workload_penalty_weight": 84.06676343906496,
"distance_penalty_weight": 1.5413441475020342,
"cluster_radius_km": 3.911615413718933,
"search_time_limit_seconds": 14,
"road_factor": 1.4812141284424145
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.265650750564059,
"max_kitchen_distance_km": 3.590986817226879,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8536491441751559,
"workload_penalty_weight": 83.53289668387433,
"distance_penalty_weight": 1.529774802118949,
"cluster_radius_km": 3.572233786654972,
"search_time_limit_seconds": 15,
"road_factor": 1.485395954896316
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.263343465055543,
"max_kitchen_distance_km": 3.7746106852600296,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8456925598017999,
"workload_penalty_weight": 86.05760075611829,
"distance_penalty_weight": 1.5496670626377171,
"cluster_radius_km": 3.4692879161186077,
"search_time_limit_seconds": 15,
"road_factor": 1.4938443091991387
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.225549460912673,
"max_kitchen_distance_km": 3.546815323022868,
"max_orders_per_rider": 17,
"ideal_load": 2,
"workload_balance_threshold": 0.8538034239262067,
"workload_penalty_weight": 79.43517045634971,
"distance_penalty_weight": 1.3116923117558434,
"cluster_radius_km": 3.88979206962715,
"search_time_limit_seconds": 14,
"road_factor": 1.4911856069021672
},
"score": 89.29891967773438
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-07T11:17:51.094393",
"training_rows": 110,
"n_trials": 100,
"best_predicted_quality": 89.4,
"best_params": {
"max_pickup_distance_km": 7.130020162334684,
"max_kitchen_distance_km": 4.280839128384073,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8854582632265207,
"workload_penalty_weight": 105.43303608103864,
"distance_penalty_weight": 2.3152400473443335,
"cluster_radius_km": 4.722786290266237,
"search_time_limit_seconds": 13,
"road_factor": 1.5274307417515143
},
"validation": {
"r2_score": 0.6382,
"mae": 7.893,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-7.9 pts (R2=0.64, trust=good)"
},
"baseline_stats": {
"avg_quality": 70.8,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 110
},
"feature_importance": {
"rolling_avg_quality_5": 33.0,
"quality_delta_10": 23.79,
"num_orders": 16.93,
"hour": 12.16,
"num_riders": 5.79,
"day_of_week": 3.89,
"max_pickup_distance_km": 1.57,
"ideal_load": 0.83,
"workload_balance_threshold": 0.82,
"max_kitchen_distance_km": 0.75,
"distance_penalty_weight": 0.25,
"search_time_limit_seconds": 0.08,
"workload_penalty_weight": 0.07,
"is_peak": 0.04,
"max_orders_per_rider": 0.03,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 7.130020162334684,
"max_kitchen_distance_km": 4.280839128384073,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8854582632265207,
"workload_penalty_weight": 105.43303608103864,
"distance_penalty_weight": 2.3152400473443335,
"cluster_radius_km": 4.722786290266237,
"search_time_limit_seconds": 13,
"road_factor": 1.5274307417515143
},
"score": 89.39888000488281
},
{
"params": {
"max_pickup_distance_km": 7.159371587069677,
"max_kitchen_distance_km": 4.033386033322248,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.863536050890365,
"workload_penalty_weight": 97.43265762258073,
"distance_penalty_weight": 1.9100499560802082,
"cluster_radius_km": 4.511755856356149,
"search_time_limit_seconds": 14,
"road_factor": 1.4939199795886327
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.237839336535851,
"max_kitchen_distance_km": 3.663365702556132,
"max_orders_per_rider": 16,
"ideal_load": 4,
"workload_balance_threshold": 0.8735336296938158,
"workload_penalty_weight": 87.18895234690117,
"distance_penalty_weight": 1.902615724431142,
"cluster_radius_km": 4.135522505489794,
"search_time_limit_seconds": 14,
"road_factor": 1.4941578228086358
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.209008794453106,
"max_kitchen_distance_km": 3.5871901473162935,
"max_orders_per_rider": 17,
"ideal_load": 4,
"workload_balance_threshold": 0.8636601075743638,
"workload_penalty_weight": 86.88314997861353,
"distance_penalty_weight": 1.713990617922939,
"cluster_radius_km": 3.9805610734693078,
"search_time_limit_seconds": 14,
"road_factor": 1.4709255743019745
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.293606340881382,
"max_kitchen_distance_km": 3.6099841904143544,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8391162982772516,
"workload_penalty_weight": 81.78402384933284,
"distance_penalty_weight": 1.4924949118149284,
"cluster_radius_km": 4.004081091262425,
"search_time_limit_seconds": 15,
"road_factor": 1.4950180193418494
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.231818308493086,
"max_kitchen_distance_km": 3.5987025683885814,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8679819345591729,
"workload_penalty_weight": 84.66571137735836,
"distance_penalty_weight": 1.7142915230680047,
"cluster_radius_km": 3.9216203223089767,
"search_time_limit_seconds": 14,
"road_factor": 1.4831054798161563
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.300424964430984,
"max_kitchen_distance_km": 3.6131608968543274,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8475063079023154,
"workload_penalty_weight": 84.06676343906496,
"distance_penalty_weight": 1.5413441475020342,
"cluster_radius_km": 3.911615413718933,
"search_time_limit_seconds": 14,
"road_factor": 1.4812141284424145
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.265650750564059,
"max_kitchen_distance_km": 3.590986817226879,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8536491441751559,
"workload_penalty_weight": 83.53289668387433,
"distance_penalty_weight": 1.529774802118949,
"cluster_radius_km": 3.572233786654972,
"search_time_limit_seconds": 15,
"road_factor": 1.485395954896316
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.263343465055543,
"max_kitchen_distance_km": 3.7746106852600296,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8456925598017999,
"workload_penalty_weight": 86.05760075611829,
"distance_penalty_weight": 1.5496670626377171,
"cluster_radius_km": 3.4692879161186077,
"search_time_limit_seconds": 15,
"road_factor": 1.4938443091991387
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.225549460912673,
"max_kitchen_distance_km": 3.546815323022868,
"max_orders_per_rider": 17,
"ideal_load": 2,
"workload_balance_threshold": 0.8538034239262067,
"workload_penalty_weight": 79.43517045634971,
"distance_penalty_weight": 1.3116923117558434,
"cluster_radius_km": 3.88979206962715,
"search_time_limit_seconds": 14,
"road_factor": 1.4911856069021672
},
"score": 89.29891967773438
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-07T14:04:02.609922",
"training_rows": 114,
"n_trials": 150,
"best_predicted_quality": 89.4,
"best_params": {
"max_pickup_distance_km": 7.130020162334684,
"max_kitchen_distance_km": 4.280839128384073,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8854582632265207,
"workload_penalty_weight": 105.43303608103864,
"distance_penalty_weight": 2.3152400473443335,
"cluster_radius_km": 4.722786290266237,
"search_time_limit_seconds": 13,
"road_factor": 1.5274307417515143
},
"validation": {
"r2_score": 0.6981,
"mae": 7.183,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-7.2 pts (R2=0.70, trust=good)"
},
"baseline_stats": {
"avg_quality": 71.4,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 114
},
"feature_importance": {
"rolling_avg_quality_5": 33.4,
"quality_delta_10": 23.95,
"num_orders": 16.78,
"hour": 11.7,
"num_riders": 5.57,
"day_of_week": 3.82,
"max_pickup_distance_km": 1.6,
"workload_balance_threshold": 0.99,
"max_kitchen_distance_km": 0.86,
"ideal_load": 0.81,
"distance_penalty_weight": 0.29,
"search_time_limit_seconds": 0.08,
"workload_penalty_weight": 0.06,
"is_peak": 0.04,
"max_orders_per_rider": 0.03,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 7.130020162334684,
"max_kitchen_distance_km": 4.280839128384073,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.8854582632265207,
"workload_penalty_weight": 105.43303608103864,
"distance_penalty_weight": 2.3152400473443335,
"cluster_radius_km": 4.722786290266237,
"search_time_limit_seconds": 13,
"road_factor": 1.5274307417515143
},
"score": 89.39888000488281
},
{
"params": {
"max_pickup_distance_km": 7.159371587069677,
"max_kitchen_distance_km": 4.033386033322248,
"max_orders_per_rider": 16,
"ideal_load": 3,
"workload_balance_threshold": 0.863536050890365,
"workload_penalty_weight": 97.43265762258073,
"distance_penalty_weight": 1.9100499560802082,
"cluster_radius_km": 4.511755856356149,
"search_time_limit_seconds": 14,
"road_factor": 1.4939199795886327
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.237839336535851,
"max_kitchen_distance_km": 3.663365702556132,
"max_orders_per_rider": 16,
"ideal_load": 4,
"workload_balance_threshold": 0.8735336296938158,
"workload_penalty_weight": 87.18895234690117,
"distance_penalty_weight": 1.902615724431142,
"cluster_radius_km": 4.135522505489794,
"search_time_limit_seconds": 14,
"road_factor": 1.4941578228086358
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.209008794453106,
"max_kitchen_distance_km": 3.5871901473162935,
"max_orders_per_rider": 17,
"ideal_load": 4,
"workload_balance_threshold": 0.8636601075743638,
"workload_penalty_weight": 86.88314997861353,
"distance_penalty_weight": 1.713990617922939,
"cluster_radius_km": 3.9805610734693078,
"search_time_limit_seconds": 14,
"road_factor": 1.4709255743019745
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.293606340881382,
"max_kitchen_distance_km": 3.6099841904143544,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8391162982772516,
"workload_penalty_weight": 81.78402384933284,
"distance_penalty_weight": 1.4924949118149284,
"cluster_radius_km": 4.004081091262425,
"search_time_limit_seconds": 15,
"road_factor": 1.4950180193418494
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.231818308493086,
"max_kitchen_distance_km": 3.5987025683885814,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8679819345591729,
"workload_penalty_weight": 84.66571137735836,
"distance_penalty_weight": 1.7142915230680047,
"cluster_radius_km": 3.9216203223089767,
"search_time_limit_seconds": 14,
"road_factor": 1.4831054798161563
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.300424964430984,
"max_kitchen_distance_km": 3.6131608968543274,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8475063079023154,
"workload_penalty_weight": 84.06676343906496,
"distance_penalty_weight": 1.5413441475020342,
"cluster_radius_km": 3.911615413718933,
"search_time_limit_seconds": 14,
"road_factor": 1.4812141284424145
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.265650750564059,
"max_kitchen_distance_km": 3.590986817226879,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8536491441751559,
"workload_penalty_weight": 83.53289668387433,
"distance_penalty_weight": 1.529774802118949,
"cluster_radius_km": 3.572233786654972,
"search_time_limit_seconds": 15,
"road_factor": 1.485395954896316
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.263343465055543,
"max_kitchen_distance_km": 3.7746106852600296,
"max_orders_per_rider": 19,
"ideal_load": 2,
"workload_balance_threshold": 0.8456925598017999,
"workload_penalty_weight": 86.05760075611829,
"distance_penalty_weight": 1.5496670626377171,
"cluster_radius_km": 3.4692879161186077,
"search_time_limit_seconds": 15,
"road_factor": 1.4938443091991387
},
"score": 89.3228530883789
},
{
"params": {
"max_pickup_distance_km": 7.225549460912673,
"max_kitchen_distance_km": 3.546815323022868,
"max_orders_per_rider": 17,
"ideal_load": 2,
"workload_balance_threshold": 0.8538034239262067,
"workload_penalty_weight": 79.43517045634971,
"distance_penalty_weight": 1.3116923117558434,
"cluster_radius_km": 3.88979206962715,
"search_time_limit_seconds": 14,
"road_factor": 1.4911856069021672
},
"score": 89.29891967773438
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-08T01:59:25.823452",
"training_rows": 120,
"n_trials": 100,
"best_predicted_quality": 92.25,
"best_params": {
"max_pickup_distance_km": 8.06481043213385,
"max_kitchen_distance_km": 3.4015023381031066,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8854774976463162,
"workload_penalty_weight": 71.31874178529236,
"distance_penalty_weight": 5.251800998756471,
"cluster_radius_km": 3.1742579527544135,
"search_time_limit_seconds": 15,
"road_factor": 1.4514851515502691
},
"validation": {
"r2_score": 0.616,
"mae": 7.429,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-7.4 pts (R2=0.62, trust=good)"
},
"baseline_stats": {
"avg_quality": 72.2,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 120
},
"feature_importance": {
"rolling_avg_quality_5": 33.36,
"quality_delta_10": 23.75,
"num_orders": 16.69,
"hour": 11.65,
"num_riders": 5.46,
"day_of_week": 4.1,
"max_pickup_distance_km": 1.61,
"workload_balance_threshold": 1.09,
"max_kitchen_distance_km": 0.96,
"ideal_load": 0.78,
"distance_penalty_weight": 0.32,
"search_time_limit_seconds": 0.09,
"workload_penalty_weight": 0.07,
"is_peak": 0.04,
"max_orders_per_rider": 0.03,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 8.06481043213385,
"max_kitchen_distance_km": 3.4015023381031066,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8854774976463162,
"workload_penalty_weight": 71.31874178529236,
"distance_penalty_weight": 5.251800998756471,
"cluster_radius_km": 3.1742579527544135,
"search_time_limit_seconds": 15,
"road_factor": 1.4514851515502691
},
"score": 92.25444030761719
},
{
"params": {
"max_pickup_distance_km": 8.192046567640352,
"max_kitchen_distance_km": 3.255736910817752,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8861488034083437,
"workload_penalty_weight": 64.69295331787431,
"distance_penalty_weight": 4.885948258458615,
"cluster_radius_km": 3.2315218916206643,
"search_time_limit_seconds": 15,
"road_factor": 1.4489842722670299
},
"score": 92.25444030761719
},
{
"params": {
"max_pickup_distance_km": 8.465745263942209,
"max_kitchen_distance_km": 3.1508636771017096,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8865213031808884,
"workload_penalty_weight": 73.71163228634174,
"distance_penalty_weight": 4.967498460686126,
"cluster_radius_km": 3.1698973794905356,
"search_time_limit_seconds": 15,
"road_factor": 1.422456216687863
},
"score": 92.25444030761719
},
{
"params": {
"max_pickup_distance_km": 8.658751131791412,
"max_kitchen_distance_km": 3.1289847468246923,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8890167428098635,
"workload_penalty_weight": 59.53054150526803,
"distance_penalty_weight": 5.07974040945962,
"cluster_radius_km": 2.8353557151054263,
"search_time_limit_seconds": 15,
"road_factor": 1.4182651473905141
},
"score": 92.25444030761719
},
{
"params": {
"max_pickup_distance_km": 8.577015198480908,
"max_kitchen_distance_km": 2.78301183338396,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8877654202870595,
"workload_penalty_weight": 51.21011204233429,
"distance_penalty_weight": 4.9175274061818355,
"cluster_radius_km": 2.6312971349957284,
"search_time_limit_seconds": 15,
"road_factor": 1.4249666800020322
},
"score": 92.25444030761719
},
{
"params": {
"max_pickup_distance_km": 8.532598643804405,
"max_kitchen_distance_km": 2.6280764984826943,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8869941742261025,
"workload_penalty_weight": 56.52753449139206,
"distance_penalty_weight": 4.802785620267564,
"cluster_radius_km": 2.8517992927555738,
"search_time_limit_seconds": 15,
"road_factor": 1.4242780622502393
},
"score": 92.25444030761719
},
{
"params": {
"max_pickup_distance_km": 8.673634610211629,
"max_kitchen_distance_km": 2.8412478114367823,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.889386447087841,
"workload_penalty_weight": 53.3795093968611,
"distance_penalty_weight": 4.621048761108392,
"cluster_radius_km": 2.77752450644401,
"search_time_limit_seconds": 15,
"road_factor": 1.4126712411250215
},
"score": 92.25444030761719
},
{
"params": {
"max_pickup_distance_km": 8.430990051063922,
"max_kitchen_distance_km": 2.9355029612495747,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8898317648909523,
"workload_penalty_weight": 54.5117727580679,
"distance_penalty_weight": 4.667163256985533,
"cluster_radius_km": 2.4951293970125565,
"search_time_limit_seconds": 15,
"road_factor": 1.4187885549435315
},
"score": 92.25444030761719
},
{
"params": {
"max_pickup_distance_km": 8.695868295786404,
"max_kitchen_distance_km": 2.736527002166546,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8869639543238491,
"workload_penalty_weight": 54.467432219870865,
"distance_penalty_weight": 4.652311237990631,
"cluster_radius_km": 2.5861719561037835,
"search_time_limit_seconds": 15,
"road_factor": 1.4175015822588442
},
"score": 92.25444030761719
},
{
"params": {
"max_pickup_distance_km": 8.665798467617625,
"max_kitchen_distance_km": 2.824631639618233,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8882049414309126,
"workload_penalty_weight": 56.35229400942434,
"distance_penalty_weight": 4.667281906791758,
"cluster_radius_km": 2.3924771955092528,
"search_time_limit_seconds": 15,
"road_factor": 1.4284644715328136
},
"score": 92.25444030761719
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-08T05:48:40.849512",
"training_rows": 130,
"n_trials": 100,
"best_predicted_quality": 92.49,
"best_params": {
"max_pickup_distance_km": 8.97552336109477,
"max_kitchen_distance_km": 2.7877044648340705,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8903020193864128,
"workload_penalty_weight": 53.40488265276959,
"distance_penalty_weight": 4.354470281012198,
"cluster_radius_km": 2.2678837392223077,
"search_time_limit_seconds": 15,
"road_factor": 1.4157581126349794
},
"validation": {
"r2_score": 0.6574,
"mae": 6.701,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-6.7 pts (R2=0.66, trust=good)"
},
"baseline_stats": {
"avg_quality": 73.37,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 130
},
"feature_importance": {
"rolling_avg_quality_5": 33.09,
"quality_delta_10": 23.84,
"num_orders": 16.42,
"hour": 11.65,
"num_riders": 5.34,
"day_of_week": 4.32,
"max_pickup_distance_km": 1.58,
"workload_balance_threshold": 1.17,
"max_kitchen_distance_km": 1.0,
"ideal_load": 0.8,
"distance_penalty_weight": 0.33,
"max_orders_per_rider": 0.26,
"search_time_limit_seconds": 0.09,
"workload_penalty_weight": 0.06,
"is_peak": 0.04,
"cluster_radius_km": 0.01
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 8.97552336109477,
"max_kitchen_distance_km": 2.7877044648340705,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8903020193864128,
"workload_penalty_weight": 53.40488265276959,
"distance_penalty_weight": 4.354470281012198,
"cluster_radius_km": 2.2678837392223077,
"search_time_limit_seconds": 15,
"road_factor": 1.4157581126349794
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.210519212090116,
"max_kitchen_distance_km": 2.795071874344803,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.890954590372547,
"workload_penalty_weight": 57.30546495575571,
"distance_penalty_weight": 4.2825502929828625,
"cluster_radius_km": 2.2309970986531154,
"search_time_limit_seconds": 15,
"road_factor": 1.407023035324782
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.223563826442748,
"max_kitchen_distance_km": 2.808717963029326,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.892196769560021,
"workload_penalty_weight": 57.15330538045706,
"distance_penalty_weight": 4.282867731690668,
"cluster_radius_km": 2.2270651869785745,
"search_time_limit_seconds": 15,
"road_factor": 1.403707328692158
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.157491797214524,
"max_kitchen_distance_km": 2.810126480283359,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8917683811761372,
"workload_penalty_weight": 57.74787593216373,
"distance_penalty_weight": 4.3249511318795255,
"cluster_radius_km": 2.1959915582659053,
"search_time_limit_seconds": 15,
"road_factor": 1.4003360081268916
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.16568429375528,
"max_kitchen_distance_km": 2.8090951982962844,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8909300879611156,
"workload_penalty_weight": 57.96924359592614,
"distance_penalty_weight": 4.356115233659841,
"cluster_radius_km": 2.1640543998081037,
"search_time_limit_seconds": 15,
"road_factor": 1.4050040294906794
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.259104291226768,
"max_kitchen_distance_km": 2.338588217223744,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8941495097259085,
"workload_penalty_weight": 58.30632718290698,
"distance_penalty_weight": 4.317355430608995,
"cluster_radius_km": 2.160490975141093,
"search_time_limit_seconds": 15,
"road_factor": 1.3994981879420294
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.318117638956453,
"max_kitchen_distance_km": 2.8273035648398968,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.88987932201009,
"workload_penalty_weight": 57.82043331508467,
"distance_penalty_weight": 4.317908076902964,
"cluster_radius_km": 2.165564764616809,
"search_time_limit_seconds": 15,
"road_factor": 1.398943484975189
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.30238269859597,
"max_kitchen_distance_km": 2.8712278434223046,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8892855074968387,
"workload_penalty_weight": 59.298723357157364,
"distance_penalty_weight": 4.253012634451528,
"cluster_radius_km": 1.962817701799511,
"search_time_limit_seconds": 15,
"road_factor": 1.3987881342234323
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.228587208865775,
"max_kitchen_distance_km": 2.7902336946097517,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8931229523479859,
"workload_penalty_weight": 58.672651882896744,
"distance_penalty_weight": 4.295307426122445,
"cluster_radius_km": 1.993660839663039,
"search_time_limit_seconds": 15,
"road_factor": 1.3993241972723316
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.199491733110056,
"max_kitchen_distance_km": 2.8798175414522116,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8907560961453739,
"workload_penalty_weight": 59.605005662034905,
"distance_penalty_weight": 4.267902417175325,
"cluster_radius_km": 2.0020539902282946,
"search_time_limit_seconds": 15,
"road_factor": 1.3959721302394685
},
"score": 92.48632049560547
}
],
"pareto_frontier": []
}

View File

@@ -1,203 +0,0 @@
{
"timestamp": "2026-04-08T06:01:50.655317",
"training_rows": 135,
"n_trials": 150,
"best_predicted_quality": 92.49,
"best_params": {
"max_pickup_distance_km": 8.97552336109477,
"max_kitchen_distance_km": 2.7877044648340705,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8903020193864128,
"workload_penalty_weight": 53.40488265276959,
"distance_penalty_weight": 4.354470281012198,
"cluster_radius_km": 2.2678837392223077,
"search_time_limit_seconds": 15,
"road_factor": 1.4157581126349794
},
"validation": {
"r2_score": 0.6748,
"mae": 6.88,
"folds": 5,
"trust_level": "good",
"trust_score": 3,
"interpretation": "Predictions off by +/-6.9 pts (R2=0.67, trust=good)"
},
"baseline_stats": {
"avg_quality": 73.75,
"best_quality": 95.0,
"worst_quality": 30.0,
"sample_size": 135
},
"feature_importance": {
"rolling_avg_quality_5": 33.49,
"quality_delta_10": 22.54,
"num_orders": 16.72,
"hour": 10.72,
"num_riders": 6.87,
"day_of_week": 3.69,
"max_pickup_distance_km": 2.66,
"max_kitchen_distance_km": 1.07,
"workload_balance_threshold": 0.55,
"ideal_load": 0.4,
"distance_penalty_weight": 0.4,
"max_orders_per_rider": 0.29,
"workload_penalty_weight": 0.23,
"road_factor": 0.17,
"cluster_radius_km": 0.15,
"is_peak": 0.04
},
"top_trials": [
{
"params": {
"max_pickup_distance_km": 8.97552336109477,
"max_kitchen_distance_km": 2.7877044648340705,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8903020193864128,
"workload_penalty_weight": 53.40488265276959,
"distance_penalty_weight": 4.354470281012198,
"cluster_radius_km": 2.2678837392223077,
"search_time_limit_seconds": 15,
"road_factor": 1.4157581126349794
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.210519212090116,
"max_kitchen_distance_km": 2.795071874344803,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.890954590372547,
"workload_penalty_weight": 57.30546495575571,
"distance_penalty_weight": 4.2825502929828625,
"cluster_radius_km": 2.2309970986531154,
"search_time_limit_seconds": 15,
"road_factor": 1.407023035324782
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.223563826442748,
"max_kitchen_distance_km": 2.808717963029326,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.892196769560021,
"workload_penalty_weight": 57.15330538045706,
"distance_penalty_weight": 4.282867731690668,
"cluster_radius_km": 2.2270651869785745,
"search_time_limit_seconds": 15,
"road_factor": 1.403707328692158
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.157491797214524,
"max_kitchen_distance_km": 2.810126480283359,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8917683811761372,
"workload_penalty_weight": 57.74787593216373,
"distance_penalty_weight": 4.3249511318795255,
"cluster_radius_km": 2.1959915582659053,
"search_time_limit_seconds": 15,
"road_factor": 1.4003360081268916
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.16568429375528,
"max_kitchen_distance_km": 2.8090951982962844,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8909300879611156,
"workload_penalty_weight": 57.96924359592614,
"distance_penalty_weight": 4.356115233659841,
"cluster_radius_km": 2.1640543998081037,
"search_time_limit_seconds": 15,
"road_factor": 1.4050040294906794
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.259104291226768,
"max_kitchen_distance_km": 2.338588217223744,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8941495097259085,
"workload_penalty_weight": 58.30632718290698,
"distance_penalty_weight": 4.317355430608995,
"cluster_radius_km": 2.160490975141093,
"search_time_limit_seconds": 15,
"road_factor": 1.3994981879420294
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.318117638956453,
"max_kitchen_distance_km": 2.8273035648398968,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.88987932201009,
"workload_penalty_weight": 57.82043331508467,
"distance_penalty_weight": 4.317908076902964,
"cluster_radius_km": 2.165564764616809,
"search_time_limit_seconds": 15,
"road_factor": 1.398943484975189
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.30238269859597,
"max_kitchen_distance_km": 2.8712278434223046,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8892855074968387,
"workload_penalty_weight": 59.298723357157364,
"distance_penalty_weight": 4.253012634451528,
"cluster_radius_km": 1.962817701799511,
"search_time_limit_seconds": 15,
"road_factor": 1.3987881342234323
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.228587208865775,
"max_kitchen_distance_km": 2.7902336946097517,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8931229523479859,
"workload_penalty_weight": 58.672651882896744,
"distance_penalty_weight": 4.295307426122445,
"cluster_radius_km": 1.993660839663039,
"search_time_limit_seconds": 15,
"road_factor": 1.3993241972723316
},
"score": 92.48632049560547
},
{
"params": {
"max_pickup_distance_km": 9.199491733110056,
"max_kitchen_distance_km": 2.8798175414522116,
"max_orders_per_rider": 18,
"ideal_load": 2,
"workload_balance_threshold": 0.8907560961453739,
"workload_penalty_weight": 59.605005662034905,
"distance_penalty_weight": 4.267902417175325,
"cluster_radius_km": 2.0020539902282946,
"search_time_limit_seconds": 15,
"road_factor": 1.3959721302394685
},
"score": 92.48632049560547
}
],
"pareto_frontier": []
}

Some files were not shown because too many files have changed in this diff Show More