leg-aware capacity and wagon sharing

This commit is contained in:
Marshal
2026-07-30 17:21:44 +00:00
parent 8f25fb3e8b
commit acef6870e9
15 changed files with 653 additions and 119 deletions

View File

@@ -4139,6 +4139,7 @@ export class TrainSchedulingService {
fittingBookings,
dto.originStationId,
dto.destinationStationId,
stops,
);
violations.push(
@@ -4185,6 +4186,8 @@ export class TrainSchedulingService {
wagonPlan,
containerPlacements,
placementRules,
legByBookingId,
Math.max(1, stops.length - 1),
),
);
violations.push(
@@ -5011,6 +5014,7 @@ export class TrainSchedulingService {
bookings: Booking[],
scheduleOriginYardId: string,
scheduleDestinationYardId: string,
stops: string[],
): void {
const bookingById = new Map(bookings.map((b) => [b.id, b]));
for (const slot of wagonPlan) {
@@ -5026,13 +5030,33 @@ export class TrainSchedulingService {
b.originYardId === first.originYardId &&
b.destinationYardId === first.destinationYardId,
);
if (!sameCorridor) continue;
slot.boardYardId =
first.originYardId === scheduleOriginYardId ? null : first.originYardId;
slot.alightYardId =
first.destinationYardId === scheduleDestinationYardId
? null
: first.destinationYardId;
if (sameCorridor) {
slot.boardYardId =
first.originYardId === scheduleOriginYardId ? null : first.originYardId;
slot.alightYardId =
first.destinationYardId === scheduleDestinationYardId
? null
: first.destinationYardId;
continue;
}
// Mixed corridors on one wagon (cross-leg TEU sharing): the wagon rides
// the UNION of its cargo legs. A yard missing from the stop list keeps
// the slot on the whole route so capacity is never under-occupied.
let from = Number.POSITIVE_INFINITY;
let to = Number.NEGATIVE_INFINITY;
for (const b of slotBookings) {
const f = stops.indexOf(b.originYardId);
const t = stops.indexOf(b.destinationYardId);
if (f < 0 || t <= f) {
from = Number.POSITIVE_INFINITY;
break;
}
from = Math.min(from, f);
to = Math.max(to, t);
}
if (!Number.isFinite(from) || to <= from) continue;
slot.boardYardId = from === 0 ? null : stops[from];
slot.alightYardId = to === stops.length - 1 ? null : stops[to];
}
}