场地推荐功能本地实现
parent
dd6b8ee489
commit
7257ae6485
@ -0,0 +1,224 @@
|
|||||||
|
package com.example.venue_reservation_service;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.time.DayOfWeek;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
// 定义预约类
|
||||||
|
class Reservation {
|
||||||
|
private int reservationId;
|
||||||
|
private int userId;
|
||||||
|
private int venueId;
|
||||||
|
private LocalTime startTime;
|
||||||
|
private LocalTime endTime;
|
||||||
|
private LocalDate reservationDate;
|
||||||
|
|
||||||
|
public Reservation(int reservationId, int userId, int venueId, LocalTime startTime, LocalTime endTime, LocalDate reservationDate) {
|
||||||
|
this.reservationId = reservationId;
|
||||||
|
this.userId = userId;
|
||||||
|
this.venueId = venueId;
|
||||||
|
this.startTime = startTime;
|
||||||
|
this.endTime = endTime;
|
||||||
|
this.reservationDate = reservationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVenueId() {
|
||||||
|
return venueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalTime getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalTime getEndTime() {
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getReservationDate() {
|
||||||
|
return reservationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DayOfWeek getDayOfWeek() {
|
||||||
|
return reservationDate.getDayOfWeek();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDurationHours() {
|
||||||
|
return Duration.between(startTime, endTime).toHours();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义场地推荐类
|
||||||
|
class VenueRecommender {
|
||||||
|
private List<Reservation> reservations;
|
||||||
|
|
||||||
|
public VenueRecommender(List<Reservation> reservations) {
|
||||||
|
this.reservations = reservations;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 推荐用户未来最可能预约的场地和时间段
|
||||||
|
public Map<String, Object> recommendMostLikelyVenueAndTimePeriod(int targetUserId) {
|
||||||
|
// 用于存储每个场地的预约次数
|
||||||
|
Map<Integer, Integer> venueCountMap = new HashMap<>();
|
||||||
|
// 用于存储每个场地最近一次的预约日期
|
||||||
|
Map<Integer, LocalDate> venueLastDateMap = new HashMap<>();
|
||||||
|
// 用于统计用户在一周各天的预约次数
|
||||||
|
Map<DayOfWeek, Integer> dayOfWeekCountMap = new HashMap<>();
|
||||||
|
// 用于统计用户在不同时间段的预约次数
|
||||||
|
Map<LocalTime, Integer> timeSlotCountMap = new HashMap<>();
|
||||||
|
// 用于统计不同时长的预约次数
|
||||||
|
Map<Long, Integer> durationCountMap = new HashMap<>();
|
||||||
|
|
||||||
|
for (Reservation reservation : reservations) {
|
||||||
|
if (reservation.getUserId() == targetUserId) {
|
||||||
|
int venueId = reservation.getVenueId();
|
||||||
|
// 更新场地的预约次数
|
||||||
|
venueCountMap.put(venueId, venueCountMap.getOrDefault(venueId, 0) + 1);
|
||||||
|
// 更新场地最近一次的预约日期
|
||||||
|
LocalDate currentDate = reservation.getReservationDate();
|
||||||
|
if (!venueLastDateMap.containsKey(venueId) || currentDate.isAfter(venueLastDateMap.get(venueId))) {
|
||||||
|
venueLastDateMap.put(venueId, currentDate);
|
||||||
|
}
|
||||||
|
// 更新一周各天的预约次数
|
||||||
|
DayOfWeek dayOfWeek = reservation.getDayOfWeek();
|
||||||
|
dayOfWeekCountMap.put(dayOfWeek, dayOfWeekCountMap.getOrDefault(dayOfWeek, 0) + 1);
|
||||||
|
// 更新不同时间段的预约次数
|
||||||
|
LocalTime startTime = reservation.getStartTime();
|
||||||
|
timeSlotCountMap.put(startTime, timeSlotCountMap.getOrDefault(startTime, 0) + 1);
|
||||||
|
// 更新不同时长的预约次数
|
||||||
|
long duration = reservation.getDurationHours();
|
||||||
|
durationCountMap.put(duration, durationCountMap.getOrDefault(duration, 0) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mostLikelyVenue = -1;
|
||||||
|
int maxCount = -1;
|
||||||
|
LocalDate latestDate = LocalDate.MIN;
|
||||||
|
|
||||||
|
for (Map.Entry<Integer, Integer> entry : venueCountMap.entrySet()) {
|
||||||
|
int venueId = entry.getKey();
|
||||||
|
int count = entry.getValue();
|
||||||
|
LocalDate lastDate = venueLastDateMap.get(venueId);
|
||||||
|
|
||||||
|
if (count > maxCount || (count == maxCount && lastDate.isAfter(latestDate))) {
|
||||||
|
mostLikelyVenue = venueId;
|
||||||
|
maxCount = count;
|
||||||
|
latestDate = lastDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找出用户预约最多的星期几
|
||||||
|
DayOfWeek mostLikelyDay = null;
|
||||||
|
int maxDayCount = -1;
|
||||||
|
for (Map.Entry<DayOfWeek, Integer> entry : dayOfWeekCountMap.entrySet()) {
|
||||||
|
DayOfWeek day = entry.getKey();
|
||||||
|
int dayCount = entry.getValue();
|
||||||
|
if (dayCount > maxDayCount) {
|
||||||
|
mostLikelyDay = day;
|
||||||
|
maxDayCount = dayCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找出用户预约最多的时间段
|
||||||
|
LocalTime mostLikelyStartTime = null;
|
||||||
|
int maxTimeSlotCount = -1;
|
||||||
|
for (Map.Entry<LocalTime, Integer> entry : timeSlotCountMap.entrySet()) {
|
||||||
|
LocalTime startTime = entry.getKey();
|
||||||
|
int timeSlotCount = entry.getValue();
|
||||||
|
if (timeSlotCount > maxTimeSlotCount) {
|
||||||
|
mostLikelyStartTime = startTime;
|
||||||
|
maxTimeSlotCount = timeSlotCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找出用户最常见的预约时长
|
||||||
|
long mostLikelyDuration = -1;
|
||||||
|
int maxDurationCount = -1;
|
||||||
|
for (Map.Entry<Long, Integer> entry : durationCountMap.entrySet()) {
|
||||||
|
long duration = entry.getKey();
|
||||||
|
int durationCount = entry.getValue();
|
||||||
|
if (durationCount > maxDurationCount) {
|
||||||
|
mostLikelyDuration = duration;
|
||||||
|
maxDurationCount = durationCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据当前日期找到下一个最可能预约的日期
|
||||||
|
LocalDate now = LocalDate.now();
|
||||||
|
LocalDate nextMostLikelyDate = now;
|
||||||
|
while (nextMostLikelyDate.getDayOfWeek()!= mostLikelyDay || nextMostLikelyDate.isBefore(now)) {
|
||||||
|
nextMostLikelyDate = nextMostLikelyDate.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalTime mostLikelyEndTime = mostLikelyStartTime.plusHours(mostLikelyDuration);
|
||||||
|
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put("venueId", mostLikelyVenue);
|
||||||
|
result.put("date", nextMostLikelyDate);
|
||||||
|
result.put("startTime", mostLikelyStartTime);
|
||||||
|
result.put("endTime", mostLikelyEndTime);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class tuijian {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
List<Reservation> reservations = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
FileInputStream file = new FileInputStream(new File("F:\\WeChat Files\\wxid_px2vbvrm2uy711\\FileStorage\\File\\2025-05\\reservation-ff7a1.xlsx"));
|
||||||
|
XSSFWorkbook workbook = new XSSFWorkbook(file);
|
||||||
|
XSSFSheet sheet = workbook.getSheet("模板");
|
||||||
|
|
||||||
|
for (Row row : sheet) {
|
||||||
|
if (row.getRowNum() == 0) {
|
||||||
|
continue; // 跳过表头行
|
||||||
|
}
|
||||||
|
int reservationId = (int) row.getCell(0).getNumericCellValue();
|
||||||
|
int userId = (int) row.getCell(1).getNumericCellValue();
|
||||||
|
int venueId = (int) row.getCell(2).getNumericCellValue();
|
||||||
|
String startTimeStr = row.getCell(3).getStringCellValue();
|
||||||
|
String endTimeStr = row.getCell(4).getStringCellValue();
|
||||||
|
// 去除日期字符串两端的空白字符
|
||||||
|
String reservationDateStr = row.getCell(5).getStringCellValue().trim();
|
||||||
|
|
||||||
|
LocalTime startTime = LocalTime.parse(startTimeStr);
|
||||||
|
LocalTime endTime = LocalTime.parse(endTimeStr);
|
||||||
|
LocalDate reservationDate = LocalDate.parse(reservationDateStr);
|
||||||
|
|
||||||
|
reservations.add(new Reservation(reservationId, userId, venueId, startTime, endTime, reservationDate));
|
||||||
|
}
|
||||||
|
|
||||||
|
workbook.close();
|
||||||
|
file.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
VenueRecommender recommender = new VenueRecommender(reservations);
|
||||||
|
int targetUserId = 16;
|
||||||
|
Map<String, Object> recommendedResult = recommender.recommendMostLikelyVenueAndTimePeriod(targetUserId);
|
||||||
|
|
||||||
|
System.out.println("用户 " + targetUserId + " 未来最可能预约的场地编号: " + recommendedResult.get("venueId"));
|
||||||
|
System.out.println("未来最可能预约的日期: " + recommendedResult.get("date"));
|
||||||
|
System.out.println("未来最可能预约的开始时间: " + recommendedResult.get("startTime"));
|
||||||
|
System.out.println("未来最可能预约的结束时间: " + recommendedResult.get("endTime"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue