Gán điểm kết thúc của chặng trước làm điểm khởi hành của chặng sau

This commit is contained in:
2026-06-14 10:11:33 +07:00
parent bf63510980
commit ec650fb45d
10 changed files with 111 additions and 16 deletions
+50 -4
View File
@@ -383,20 +383,57 @@ class RoutingController {
@Post('optimize/:legId')
async optimize(@Param('legId', ParseUUIDPipe) legId: string) {
const currentLeg = await this.prisma.leg.findUnique({
where: { id: legId },
});
if (!currentLeg) throw new NotFoundException('Không tìm thấy chặng');
const locations = await this.prisma.location.findMany({
where: { legId },
});
if (locations.length <= 2) return locations;
if (locations.length === 0) return { locations: [], totalDistance: 0 };
// KHAI BÁO startAnchor ở đầu hàm để tránh lỗi scope TS2304
let startAnchor: any = null;
// Tìm địa điểm cuối cùng của chặng trước đó
const prevLeg = await this.prisma.leg.findFirst({
where: {
tourId: currentLeg.tourId,
sequence: currentLeg.sequence - 1
},
include: { locations: { orderBy: { plannedStart: 'asc' } } }
});
if (prevLeg?.locations?.length) {
startAnchor = prevLeg.locations[prevLeg.locations.length - 1];
}
if (locations.length <= 2 && !startAnchor) return { locations, totalDistance: 0 };
// Thuật toán Greedy TSP đơn giản để tối ưu hóa lộ trình
const optimized = [];
const unvisited = [...locations];
// Bắt đầu với địa điểm có thời gian dự kiến sớm nhất hiện tại
let current = unvisited.sort((a, b) =>
(a.plannedStart?.getTime() || 0) - (b.plannedStart?.getTime() || 0)
).shift()!;
let current: any;
if (startAnchor) {
let nearestIdx = 0;
let minDist = Infinity;
for (let i = 0; i < unvisited.length; i++) {
const d = calculateDistance(startAnchor.latitude, startAnchor.longitude, unvisited[i].latitude, unvisited[i].longitude);
if (d < minDist) {
minDist = d;
nearestIdx = i;
}
}
current = unvisited.splice(nearestIdx, 1)[0];
} else {
current = unvisited.sort((a, b) =>
(a.plannedStart?.getTime() || 0) - (b.plannedStart?.getTime() || 0)
).shift()!;
}
optimized.push(current);
while (unvisited.length > 0) {
@@ -416,6 +453,15 @@ class RoutingController {
// Tính toán tổng quãng đường di chuyển của chặng (km)
let totalDistance = 0;
// Cộng thêm quãng đường từ chặng trước nối sang chặng này
if (startAnchor) {
totalDistance += calculateDistance(
startAnchor.latitude, startAnchor.longitude,
optimized[0].latitude, optimized[0].longitude
);
}
for (let i = 0; i < optimized.length - 1; i++) {
totalDistance += calculateDistance(
optimized[i].latitude, optimized[i].longitude,