!1 场地推荐功能本地实现

Merge pull request !1 from chenyuepan/master-algorithm
pull/2/MERGE
chenyuepan 1 month ago committed by Gitee
commit 107565d193
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F

@ -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…
Cancel
Save