| """Distance and travel-time matrices. |
| |
| Node ordering convention used everywhere in this project: |
| nodes[0 .. n_adjusters-1] = adjuster home locations (route start/end) |
| nodes[n_adjusters .. ] = claim property locations |
| |
| The solver only ever reads these matrices, so replacing haversine estimates |
| with real drive times (OSRM's /table endpoint, Google/HERE Distance Matrix) |
| means swapping build_matrices() and nothing else. |
| """ |
|
|
| from __future__ import annotations |
|
|
| import math |
|
|
| import config |
| from data_gen import Adjuster, Claim |
|
|
| EARTH_RADIUS_MILES = 3958.8 |
|
|
|
|
| def haversine_miles(lat1: float, lon1: float, lat2: float, lon2: float) -> float: |
| p1, p2 = math.radians(lat1), math.radians(lat2) |
| dp = math.radians(lat2 - lat1) |
| dl = math.radians(lon2 - lon1) |
| a = math.sin(dp / 2) ** 2 + math.cos(p1) * math.cos(p2) * math.sin(dl / 2) ** 2 |
| return 2 * EARTH_RADIUS_MILES * math.asin(math.sqrt(a)) |
|
|
|
|
| def matrices_from_coords(coords: list[tuple[float, float]] |
| ) -> tuple[list[list[float]], list[list[int]]]: |
| """(miles, minutes) matrices over an arbitrary coordinate list - |
| haversine * circuity, minutes as integers for the solvers.""" |
| n = len(coords) |
| miles = [[0.0] * n for _ in range(n)] |
| minutes = [[0] * n for _ in range(n)] |
| for i in range(n): |
| for j in range(i + 1, n): |
| d = haversine_miles(*coords[i], *coords[j]) * config.CIRCUITY_FACTOR |
| t = int(round(d / config.AVG_SPEED_MPH * 60)) |
| miles[i][j] = miles[j][i] = d |
| minutes[i][j] = minutes[j][i] = t |
| return miles, minutes |
|
|
|
|
| def build_matrices(adjusters: list[Adjuster], claims: list[Claim] |
| ) -> tuple[list[list[float]], list[list[int]]]: |
| """Return (miles_matrix, travel_minutes_matrix) over all nodes. |
| |
| Miles are road-approximated (haversine * circuity factor); minutes are |
| integers as required by OR-Tools. |
| """ |
| coords = [(a.home_lat, a.home_lon) for a in adjusters] |
| coords += [(c.lat, c.lon) for c in claims] |
| return matrices_from_coords(coords) |
|
|