Pre Merge pull request !1 from chenyuepan/master-algorithm
commit
32802854f9
@ -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();
|
||||
}
|
||||
}
|
||||
//1
|
||||
// 定义场地推荐类
|
||||
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