-
Notifications
You must be signed in to change notification settings - Fork 0
Service allocation procedure
The service allocation module determines which facilities (e.g. schools) to keep open and how clients (population grid cells) are assigned to them, balancing travel costs against scale inefficiency. The workflow is split between two environments:
-
GeoDMS (
Analyses.dms): computes the origin–destination (OD) matrix and exports input data to Arrow files. - Julia: reads those Arrow files, solves the facility location and assignment problem, and writes results back to an Arrow file for use in GeoDMS.
GeoDMS (Analyses.dms)
└─▶ {country}_od.arrow (OD pairs: client, facility, t_ij, d_ij)
└─▶ {country}_i.arrow (clients: id, population)
└─▶ {country}_j.arrow (facilities: id)
│
▼
Julia (one of the solvers below)
│
▼
{country}_j_greedy.arrow (facilities: id, open)
or
{country}_j_mip.arrow
│
▼
GeoDMS (Analyses.dms)
└─▶ FacilityRemainsOpen, Openness, accessibility outputs
- Clients:
$i \in \mathcal{I}$ — population grid cells with demand$Q_i \ge 0$ - Candidate facilities:
$j \in \mathcal{J}$ — school locations
- Open decision:
$x_j \in {0,1}$ - Demand flow:
$y_{ij} \ge 0$ , fraction of client$i$ assigned to facility$j$ - Facility load:
$S_j := \sum_i y_{ij} \cdot Q_i$
Minimise total travel cost plus a scale-inefficiency penalty for under-enrolled facilities:
where
- Each client is fully assigned:
$\sum_j y_{ij} = 1 \quad \forall i$ - Assignment only to open facilities:
$y_{ij} \le x_j \quad \forall i,j$ - Deficit definition: $\text{deficit}j \ge Q{\min} \cdot x_j - S_j \quad \forall j$
| Symbol | Variable in code | Description |
|---|---|---|
min_students |
Minimum viable enrolment per facility (default: 100) | |
λ |
Penalty per unit of under-enrolment; derived as facility_cost / (min_students / 2)
|
|
facility_cost |
— | Estimated annual operating cost per facility: 2 * total_travel_time * 200 / M
|
flag |
flag |
Set to 1 to activate the penalty term, 0 to ignore it |
The AllocateKidsToSchools unit in Analyses.dms computes OD pairs using a network impedance matrix. Key outputs per OD pair:
| Field | Description |
|---|---|
client_rel |
Index of origin grid cell |
facility_rel |
Index of destination facility |
t_ij |
Travel time (seconds) along the shortest path |
d_ij |
Distance (km) |
travelcost_ij |
Monetary travel cost |
Deterrence_ij |
Distance-decay weight |
The deterrence function uses a power-law decay (
After running a Julia solver, GeoDMS reads back the open/closed status and computes:
-
FacilityRemainsOpen: boolean per facility -
Openness: a potential-based accessibility surface on the 1 km grid
All solvers share the same data loading pattern:
od = Arrow.Table(".../{country}_od.arrow")
loc = Arrow.Table(".../{country}_i.arrow")
fac = Arrow.Table(".../{country}_j.arrow")And write results as:
Arrow.write(".../{country}_j_greedy.arrow", (id = facilities, open = open_vec))where open is encoded as:
-
0= closed -
1= open and$S_j \ge Q_{\min}$ -
2= open but$S_j < Q_{\min}$ (under-enrolled)
No LP or MIP solver required. Steps:
- Start with all facilities open (filtered by expected load from nearest-facility assignment).
- Run a drop heuristic: iteratively close the facility whose removal saves the most (penalty saving minus extra travel cost for displaced clients), using a precomputed second-best facility per client.
- Repeat until no improving closure exists.
Supports a grid search over min_students and λ_factor to explore the sensitivity of the number of open facilities to these parameters:
julia greedy-nn.jl
Set run_grid = true for a grid search, false for a single run. Also supports a quadratic travel cost function
- Solve the LP relaxation of the facility location problem using HiGHS via JuMP.
- Classify facilities as: integer-open, integer-closed, or fractional.
- Start with all non-closed facilities open, then apply the drop heuristic only to fractional facilities (integer-open ones are kept fixed).
- Fix the resulting open/closed decisions and re-solve an assignment LP for optimal fractional flows.
This tends to give tighter solutions than the pure greedy approach for larger instances.
Same as lp-greedy.jl but skips the final assignment LP re-solve. Faster but assignment is from the greedy step only.
- Solve the LP relaxation.
- Fix variables that are already integer (within tolerance
tol = 1e-6). - Set remaining
$x_j$ as binary and solve the MIP using HiGHS (1% optimality gap).
Supports a force = true flag to fix all facilities open (useful for benchmarking travel costs with full network).
julia mip.jl
| Script | Method | Speed | Solution quality |
|---|---|---|---|
greedy-nn.jl |
Greedy drop | Fast | Heuristic |
lp-greedy-nn.jl |
LP + greedy drop | Medium | Better lower bound |
lp-greedy.jl |
LP + greedy + re-solve | Medium | Best heuristic |
mip.jl |
LP + MIP | Slow | Near-optimal (1% gap) |
Each client
Availability is guaranteed only for clients within designated zones (
Service providers may decline to serve sparsely populated areas. A provider
Notes 1 and 3 are special cases of 2 with
$t_{\text{zone}} = \infty$ or$0$ , respectively.
Facility cost when open:
Minimum optimal demand:
After removing fixed provision costs, the scale inefficiency costs are:
This is approximated in the objective by the
