A car-transport dispatcher for one simulated week in Finland. It prices about 1,000 dealer requests against a hidden competitor, then pays freelance drivers to move every car it wins. Everything it does follows from one estimate: the fee at which a driver takes this car in time.
We are a middleman. A dealer pays us a price to move a car, and we pay a freelance driver a fee to do it. The score is what is left over, and it only counts if at least 90% of the cars arrive on time.
Rough sizes from early practice weeks. Seeker's weeks average 18.7k. Driver fees are the largest lever: 0.1 × the typical fee across all gigs is about 2.5k a week.
The difficulty is that almost everything that decides the outcome is hidden. The model is easiest to understand as five estimates of hidden things, each feeding one decision.
Two loops share one set of offline-fitted tables. The top loop sells: a request comes in, quote() answers, the dealer's choice teaches learn() the competitor's price this week. The bottom loop delivers: a won car is posted to the driver board, alone or paired, with a fee schedule from fees().
Blue boxes are the four functions in algo.ts (416 lines, every decision), with their steps listed inside. Dashed lines are table lookups, and each table names the functions that read it. The engine (core/engine.ts) does the mechanics and calls the four. The numbered sections below give the formulas behind each box.
The design choices that matter most. Each is covered in detail in the numbered sections below.
The model estimates the fee at which a driver takes a car in time. Which options we sell, the price we quote, the fee schedule and the pairing of cars all read it from the same booking model, so the parts cannot disagree.
The competitor's price is never shown; we only learn whether we won. A small filter turns every answer into an estimate of this week's price level, per weekday and per lane, and the next quote already uses it.
worth +419 ± 101 and +303 ± 83 EUR a weekOnce a week the competitor goes down in one region. The model holds a probability over 31 possibilities (none, or around each of 30 towns) and prices against a blend of the competitor and its dearer backup.
worth +430 ± 144 EUR a weekThe planned driver fee explained 6% of what an order ended up costing. Trees fitted on 156,000 finished orders explain 27%, and using them in the price choice was one of the largest gains.
worth +644 ± 106 EUR a weekAbout 200 drivers carry everything, so driver time has a price inside every quote: 4 EUR per driver-hour. A full town or a full deadline day costs the dealer 25% more instead of getting a no.
worth +600 to +800 EUR a weekThe booking model shows that paying above 1.4 × the typical fee buys no extra bookings, so the ramp stops at 1.45. Once a car is late whatever we pay, the fee drops back to 0.83 instead of climbing.
fee floor and late fee: +530 ± 116 EUR a weekEach rule was kept only if it earned margin on fresh server weeks with the same seeds, usually 48 to 96 of them. Ideas that did not pass were removed.
Every decision lives in one 416-line file with four functions, and every tunable value in one table. The engine can be restarted in the middle of the final and resumes from the server's state and its own saved learning.
A logistic model answers one question: what is the chance that a driver books this gig within the next hour, at this fee? It was fitted on 160 weeks played with random fees. It comes first because both the prices (section 2) and the driver fees (section 4) are built on it.
Slope 5.2 up to the typical fee, 1.95 from 1.0 to 1.4, then −0.97: in the model, paying above 1.4 × typical buys no extra bookings. This is why the early ramp stops at 1.45.
Reading the bars: a gig is easier to book in the morning, as a two-car gig, and when its typical fee is large. It is harder at a private pickup address, late in the evening, on Sunday, for premium cars (experienced drivers only), with long drives, and the longer it has already sat on the board.
For a gig posted now with \(H\) hours to its last pickup time (at most 72), the planner tries every opening fee from 0.706 to 1.6 in steps of 0.05 and every hourly raise in {0, 0.05, 0.1, 0.2}, and walks the hours:
\(z_k\) is the gig-and-clock part of the logit in hour \(k\), \(f\) the fee term above, and 4 × typical is what a gig without a driver is counted as (lateCost). The cheapest (open, raise) pair wins. Raises stop after 4 steps.
The booking shift. \(b\) = bookShift = 0.2 is added to the logit, but only when planning fee schedules. In quote() the planner runs with \(b = 0\). The booking model is a little too pessimistic about how fast drivers book, so the schedules can open lower, while which options are sold and at what price stays the same. Alone this was worth about +300 a week with orders unchanged.
Each request offers up to three delivery options (same day, next day, within 3 days). The model decides which options to sell, picks one markup for the whole request, then adjusts each option's price.
For every option the fee planner (section 1) returns the cheapest schedule, its expected cost, and the chance a driver books before the last pickup time. The last pickup time is the deadline minus the drive, moved by anything the dealer's note says (car ready later, deliver earlier, real site hours).
The planner's expected fee is a weak predictor of what an order really ends up costing (held-out R² 0.06). Gradient-boosted trees fitted on 156,312 won orders predict the realized cost from 38 quote-time inputs (R² 0.27): fees with raises, refunds, failed visits, undelivered cars. Seeker over-weights the trees.
With w = 1.25 this is 1.25 × trees − 0.25 × plan: it pushes past the trees, away from the plan. typical is the lane-table typical fee, not the dealer's noisy number.
The competitor's price is never shown. The model keeps a running estimate of its log price for this request, \(\mu\), as a fixed part from the offline table plus this week's learned levels:
m is our price as a multiple of list. v is the filter's own variance for this request, so early in the week (large doubt) the curve is flatter. With s = 0.1, a 1% higher price costs about 10% of the win odds.
Between 08:00 and 18:00 the model also carries a belief that the competitor is down around this pickup today (share \(q\)), where dealers buy from a backup about 1.2 × dearer. The win chance becomes a mixture:
Bars mean the average over the sellable options. The capacity cost is a shadow price on driver time: drivers are the bottleneck, so a car that holds a driver longer must earn more. It is subtracted in the choice only, never paid.
The search window slides by \(\Delta\), the sum of these shifts (all in multiples of list):
| Condition | Shift Δ | Why |
|---|---|---|
| Pickup town full: our undelivered orders from it ≥ 3 × drivers living within 30 km | +0.25 | Ration drivers by price instead of declining |
| Round trip: an open one-car gig of ours delivers within 40 km of this pickup and starts within 40 km of this delivery | −0.05 | The driver needs no trip home |
| Outage belief at this pickup (share q) | +0.30 × q | The dealer's other choice is the dearer backup |
| Cheap week or cheap day: learned level x_week + x_weekday below 0 | level, at most −0.20 | A fixed floor would lose whole days in a price war |
A deadline day (Mon to Fri) is full when our orders due that day reach 0.10 × the week's driver roster. Friday holds 40% of the lates, Monday deadlines have slack. If no option clears the 10% profit gate, the request is declined.
Section 2 uses two quantities that change during the week: the competitor's price level and the chance of an outage. Both are updated after every answer.
The competitor sits 26% to 54% above list, at a different level every week, with a weekday swing and a level per lane inside the week. The state \(x\) holds one number for the week, five for the weekdays and one per lane (pickup × delivery town, single cars, created when first asked). Every won or lost quote is one logistic observation; the update is a one-step Kalman-style correction.
\(h\) marks which levels this request touches. \(P\) starts diagonal with prior SDs in log price: week 0.05, weekday 0.14, lane 0.06. Winning more than expected raises the levels, and the next quotes go out dearer. Dealer and town levels exist in the code but have prior 0 (tested, no gain).
Once a week the competitor is down in one region (a town and everything within 80 km) for a working day. The model holds a probability over 31 hypotheses: no outage today, or an outage around each of the 30 towns.
\(\ell_i\) is the chance of the answer we actually got (won or lost) at the price we quoted, clipped to 0.08 to 0.92 so one answer cannot decide it. \(q\) feeds the mixture in step 3 and the +0.30 × q shift in step 4. The price filter reads each answer against the expected price there, so an outage does not drag the whole weekday level up. Once the belief passes 0.9 on a day, the outage counts as seen and its prior is 0 for the rest of the week.
When a gig is posted, the planner from section 1 sets its opening fee and hourly raises. Fixed rules take over as the last pickup time approaches.
Fee as a multiple of the typical fee, while nobody has booked. The opening fee and raise in this example are illustrative; the other levels are the model's parameters. The warning schedule restarts at 1.30, which is under the ramp's top of 1.45.
A driver who takes two cars in a chain pays one trip to the first pickup and one trip home, and the booking model gives two-car gigs a large bonus (+1.13 in the logit). When a one-car order is won, the engine checks every open, unbooked one-car gig of ours in both orders (new car first, new car second).
| Event | Reaction |
|---|---|
| price_request | Denoise the typical fee. The dealer's typical fee carries about 13% noise that drivers mostly ignore. It is replaced by a lane-table prediction (899 lanes, with small terms for private addresses, premium, electric), unless the lane was seen fewer than 5 times. Then quote(). |
| order_won | Read the note. A note that moves the pickup or deadline, or names site hours, makes the car go alone and sets the engine's own warning timer. Otherwise try a pair, else post alone. Premium cars go to experienced drivers only; a note about plates or manual gearbox sets the audience up front. |
| deadline_close | Mark the order urgent, split its pair if any, reprice with the steep schedule. One minute after the last pickup time, reprice again with the late schedule. |
| gig_dropped / no_show | A pair is split. A single gig stays as posted. |
| gig_expired | Repost: with the next day's slot when the note gives site hours, else without stop windows. An expired pair is split. |
| visit_failed | Repost that car: later pickup if the car was not ready or the site was closed, manual-licence audience or transfer plates if that was the reason. |
| order_changed | Withdraw the gig and post again with a fresh schedule. |
| delivered | Dealer trust +1 if on time (up to 25), halved if late. Trust raises the price that dealer accepts. |
The note reader is a regex reader in Finnish, Swedish and English, 97 to 99% right on ready time, deadline, plates and manual gearbox. 42.5% of won orders carry a note, and 70% of notes change nothing.
This table summarises the parts described in sections 1 to 6. Each was added in response to a specific problem seen in played weeks, and was kept only if it earned margin on fresh server weeks with the same seeds. The last column is what the part was worth in EUR a week, tested with and without it.
| Part | The problem it solved | What it does | Worth |
|---|---|---|---|
| Knowing what a car costs | |||
| Denoised typical fee typMinN | The dealer's "typical fee" carries about 13% random noise per request. Drivers mostly ignore it, so paying by it overpays half the gigs and underpays the rest. | Replaces it with a per-lane average from 899 lanes. | +200 to +400 |
| Realized-cost trees costW | The planner's expected fee barely predicted what an order ended up costing (R² 0.06). Raises, drops, failed visits and refunds were invisible when pricing. | Trees predict the full final cost from what is known at quote time (R² 0.27). Cheap gigs turn out dearer per euro than the plan says. | +644 ± 106 |
| Hard options minBookChance, hardChance, hardPrice | Some deadline options are unlikely to find a driver in time. Refusing them all loses sales, selling them all breaks the 90% on-time line. | Three bands: refuse under 0.82, sell 20% dearer up to 0.95, normal above. | not measured alone |
| Rationing drivers | |||
| Capacity cost and a lower floor capLam, capConst, markupMin | With a high price floor, 43% of quotes sat on it, so the floor was choosing our orders. Drivers, not demand, are the limit: about 200 carry everything. | A low floor of 1.28, and a charge of 4 EUR per driver-hour on each quote, so long drives must earn more to be worth a driver. | +600 to +800 |
| Full town or deadline day capPerDriver, dueCapPer, fullPrice | Orders piled up in one town or on one deadline day and went late together. Friday-due orders held 40% of all lates. | Past a load limit, prices rise 25% instead of declining. The few orders still won pay for the risk. | keeps weeks ranked; day cap +190 |
| Price by deadline day dueMon, dueFri | Friday is the tight day, and Monday deadlines have slack because no new requests arrive over the weekend. | Friday-due +8% of list, next-Monday-due −3%. | +120 ± 63 |
| Reading the competitor | |||
| Weekday price learning pS, pWeek, pDay | The competitor sits 26% to 54% above list, different every week, and swings 12% between weekdays. One fixed price curve is wrong most days. | A filter learns a week level and a level per weekday from every win and loss. The weekday prior has to be wide (SD 0.14 in log price) or the filter learns nothing. | +419 ± 101 |
| Lane level pLane | Inside a week the competitor is consistently dear or cheap on a given lane, and 64% of requests come on a lane already asked that week. | One more learned level per lane. | +303 ± 83 (one of four sets negative) |
| Price floor follows the learned level floorLvl | In a cheap week or on a price-war day the fixed floor priced us out for whole days. | The floor drops with the learned level, by at most 0.20. | +222 ± 58 |
| Outage belief outBayes, outageK, outage | In a live test final the competitor went down around Helsinki. Priced at the floor, we won 79% of 108 requests, far too cheap, and a simple yes/no flag also fired outside the region. | A probability per region, with the win chance mixed between competitor and backup. The backup factor is 1.2 because stored quotes show wins hold up to 1.2 × and collapse by 1.3 ×. | +430 ± 144 |
| Paying drivers | |||
| Planned fee schedule openMin, openMax, raiseMax, steps, lateCost | Flat fees lost at every level tried: cheap ones miss drivers, dear ones overpay. Only 38% of gigs book at the opening fee. | Opens low and raises hourly, with the pair (open, raise) chosen per gig by expected cost. | opening floor and late fee: +530 ± 116 |
| Early ramp rampTop, rampWindowH | A gig still unbooked the evening before its pickup day is 12.6% late, a booked one 2.3%. Raising at the last minute is too late. | Climbs to 1.45 × over the last 10 hours, ending 3 hours before the last pickup. It stops at 1.45 because the booking model shows no gain past 1.4. | not measured alone |
| Late fee lateFee | Once the last pickup time has passed the order is late whatever we pay, yet the fee kept climbing. | Drops back to 0.83 × and climbs slowly. | part of the +530 |
| Cheaper fees from Thursday feeLate | In a test final, gigs posted on Thursday and Friday booked at 0.99 × typical against 0.87 on Monday: we overpaid late in the week. | Planned fees × 0.95 from Thursday on. | +168 ± 45 |
| Booking shift bookShift, bookQuote | The booking model is slightly too pessimistic about how fast drivers book. Correcting it everywhere sold more orders and cost ranked weeks. | Corrects it in the fee schedules only, so fees open lower while sales stay the same. | +320 ± 50 |
| Details that prevent failures | |||
| Note reading noteHours, pairFlags, hoursMinLeftH | Orders whose note gave real opening hours were 14 to 19% late, with 27 visits to closed sites per 100. | Reads hours, ready times, plates and gearbox from the note and plans around them. | +251 ± 94; failed visits 3.5 → 0.6 a week |
| Two-car gigs pairKm, pairSlackH, pairCap, pairTop, pairHoldH | Every single-car gig pays a driver's empty trips. But a third of the pairs that nobody booked went late. | Joins cars into a chain when the join is short and there is slack, and splits the pair after 3 hours unbooked. | the 40 km and 3 h settings: +213 ± 70 |
The values Seeker plays. Parameters that are switched off (fee tilt, price-war state, typical-fee floor) are left out.
| Name | Value | Meaning |
|---|---|---|
| Which options to sell | ||
| minBookChance | 0.95 | Normal price only above this chance of a booking in time |
| hardChance | 0.82 | Below this the option is not sold |
| hardPrice | 0.20 | Price rise for a hard option |
| costW | 1.25 | Weight of the realized-cost trees against the plan fee |
| minProfit | 0.10 | Price must be at least 1.10 × cost |
| minSlackH | 3 | Hours the deadline must leave beyond the drive |
| capPerDriver | 3 | Town is full at this many open orders per nearby driver |
| dueCapPer | 0.10 | Deadline day is full at this × roster |
| fullPrice | 0.25 | Price rise for a full town or day |
| Price search | ||
| markupMin / markupMax | 1.28 / 2.00 | Search range, × list |
| capLam, capConst | 4, 1 | Capacity cost: EUR per driver-hour, extra hours per gig |
| pairBack | 0.05 | Round-trip price cut |
| dueMon / dueFri | −0.03 / +0.08 | Price shift by deadline day |
| floorLvl | 1 | Floor follows the learned level when it is below average |
| outage, outageK | 0.30, 1.2 | Floor shift in an outage; backup price × competitor |
| outPriorMax | 0.6 | Largest prior for an outage today |
| Price filter | ||
| pS | 0.10 | Sharpness of the dealer's choice, log price |
| pWeek / pDay / pLane | 0.05 / 0.14 / 0.06 | Prior SD of the week, weekday and lane levels |
| Driver fees (× typical fee) | ||
| openMin / openMax | 0.706 / 1.6 | Range of the opening fee |
| raiseMax | 0.2 | Largest hourly raise |
| steps | 4 | Number of hourly raises |
| rampTop | 1.45 | Top of the early ramp |
| rampWindowH | 10 | Ramp starts this many hours before the last pickup time |
| steepOpen / steepStep | 1.3 / 0.15 | After a deadline warning |
| lateFee | 0.832 | After the last pickup time has passed |
| lateCost | 4 | Planner's cost of a gig with no driver |
| feeLate | 0.95 | Fee factor for gigs posted from Thursday on |
| bookShift | 0.2 | Booking logit shift, fee schedules only |
| Two-car gigs | ||
| pairKm | 40 | Largest join distance, km |
| pairSlackH | 6 | Slack needed before the tighter last pickup time |
| pairCap / pairTop | 0.9 / 1.3 | Opening cap and ramp top of a pair |
| pairHoldH | 3 | Unbooked pair is split after this many hours |
Sources: Bahn-Spread/kit-final/algo.ts, core/model.ts, core/cost.ts, core/engine.ts, core/data/*.json, research/KNOWLEDGE.md, research/LEDGER.md.