Files
hzdyjs/docs/开发文档/床位分配逻辑优化说明.md
T
2025-08-13 08:28:48 +08:00

195 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 床位分配逻辑优化说明
## 📋 优化概述
**优化时间**: 2025-01-03
**修改文件**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java`
**修改方法**: `batchAllocateBedsToCollege`
## 🎯 优化目标
将床位分配逻辑从**分散分配**调整为**连续分配**,确保同一学院的学生尽量分配在相邻的房间或同一房间内,提高宿舍管理效率。
## 🔄 分配逻辑对比
### 原有逻辑(分散分配)
```
❌ 问题:每次从不同房间各取一个床位分配给同一学院
- 房间1:床位1 → 学院A
- 房间2:床位1 → 学院A
- 房间3:床位1 → 学院A
- 房间4:床位1 → 学院A
- 房间1:床位2 → 学院A
...
结果:学院A的学生分散在所有房间
```
### 新逻辑(连续分配)
```
✅ 优化:按房间顺序连续分配床位
- 房间1:床位1-8 → 学院A(8个)
- 房间2:床位1-2 → 学院A(2个)
- 房间2:床位3-8 → 学院B(6个)
- 房间3:床位1-2 → 学院B(2个)
- 房间3:床位3-8 → 学院C(6个)
...
结果:每个学院的学生相对集中
```
## 🎯 分配示例
**场景**: 4个房间,每个房间8个床位,总计32个床位
### 学院需求
- 学院A:10个床位
- 学院B:8个床位
- 学院C:7个床位
- 学院D:7个床位
### 分配结果
```
房间1(8个床位):学院A(床位1-8)
房间2(8个床位):学院A(床位1-2)+ 学院B(床位3-8)
房间3(8个床位):学院C(床位1-7)+ 学院D(床位8)
房间4(8个床位):学院D(床位1-6)+ 空余2个床位
```
## 🔧 技术实现
### 核心算法改进
#### 1. 床位排序
```java
// 获取房间信息,建立roomId到roomCode的映射
Set<Long> roomIds = beds.stream().map(XgDormBed::getRoomId).collect(java.util.stream.Collectors.toSet());
List<XgDormRoom> rooms = xgDormRoomMapper.selectBatchIds(roomIds);
Map<Long, String> roomCodeMap = rooms.stream()
.collect(java.util.stream.Collectors.toMap(XgDormRoom::getId, XgDormRoom::getRoomCode));
// 将床位按房间顺序排列,实现连续分配
List<XgDormBed> sortedBeds = beds.stream()
.sorted((b1, b2) -> {
// 首先按房间编码排序
String roomCode1 = roomCodeMap.get(b1.getRoomId());
String roomCode2 = roomCodeMap.get(b2.getRoomId());
int roomCompare = roomCode1.compareTo(roomCode2);
if (roomCompare != 0) {
return roomCompare;
}
// 同一房间内按床位编码排序
return b1.getBedCode().compareTo(b2.getBedCode());
})
.collect(java.util.stream.Collectors.toList());
```
#### 2. 连续分配算法
```java
int currentBedIndex = 0; // 当前分配到的床位索引
for (int collegeIndex = 0; collegeIndex < bo.getCollegeIds().size(); collegeIndex++) {
Long collegeId = bo.getCollegeIds().get(collegeIndex);
int studentCount = collegeCounts.get(collegeIndex);
// 为当前学院连续分配指定数量的床位
for (int i = 0; i < studentCount; i++) {
XgDormBed bed = sortedBeds.get(currentBedIndex + i);
// 创建分配记录...
}
// 更新当前床位索引
currentBedIndex += studentCount;
}
```
### 关键优化点
#### 1. 索引管理
- **原逻辑**: 复杂的房间遍历和床位查找
- **新逻辑**: 简单的索引递增,O(1)时间复杂度
#### 2. 内存效率
- **原逻辑**: 需要维护房间分组Map和动态删除操作
- **新逻辑**: 一次性排序,线性访问,内存占用更少
#### 3. 分配可预测性
- **原逻辑**: 分配结果难以预测
- **新逻辑**: 分配结果完全可预测,便于调试和验证
#### 4. 排序优化
- **原逻辑**: 按房间ID和床位ID排序,不符合物理布局
- **新逻辑**: 按房间编码(roomCode)和床位编码(bedCode)排序,符合实际物理顺序
## 📊 优化效果
### 宿舍管理优势
1. **集中管理**: 每个学院的学生相对集中,便于管理员统一管理
2. **减少跨楼层**: 学生活动和管理主要在相邻房间,减少跨楼层流动
3. **便于统计**: 学院相关的宿舍统计更加方便
### 学生体验优势
1. **同学院聚集**: 同学院学生住宿相对集中,便于学习和生活交流
2. **减少陌生感**: 周边多为同学院学生,归属感更强
3. **便于组织活动**: 学院活动组织更加便利
### 系统性能优势
1. **算法效率**: 时间复杂度从O(n²)降低到O(n log n)
2. **内存占用**: 减少临时数据结构,内存使用更高效
3. **代码维护**: 逻辑更清晰,便于理解和维护
## 🧪 测试验证
### 测试用例1:标准分配
```
输入:
- 房间数:4个,每个8床位
- 学院需求:[10, 8, 7, 7]
预期输出:
- 房间1:学院1(全部8个)
- 房间2:学院1(2个)+ 学院2(6个)
- 房间3:学院2(2个)+ 学院3(6个)
- 房间4:学院3(1个)+ 学院4(7个)
```
### 测试用例2:边界情况
```
输入:
- 床位数:1个
- 学院数:1个
- 学院需求:[1]
预期输出:
- 成功分配1个床位给学院1
```
## 📝 注意事项
### 开发注意点
1. **排序稳定性**: 确保相同房间内床位按编码顺序排列
2. **索引边界**: 严格检查数组边界,避免越界访问
3. **事务安全**: 分配过程中如有异常,确保数据回滚
### 业务规则
1. **房间优先级**: 按房间编码(roomCode)升序分配,确保分配顺序的一致性
2. **床位顺序**: 同一房间内按床位编码(bedCode)升序分配,符合物理布局
3. **学院顺序**: 严格按照传入的学院顺序进行分配
4. **床位状态**: 只分配状态为"空闲"的床位
## 🔮 后续优化方向
### 功能增强
1. **智能分配**: 考虑学院特性(如男女比例)优化分配策略
2. **自定义规则**: 支持管理员自定义分配优先级规则
3. **冲突检测**: 提前检测可能的分配冲突并给出建议
### 性能优化
1. **批量操作**: 进一步优化数据库批量操作性能
2. **缓存机制**: 对房间和床位信息增加缓存机制
3. **异步处理**: 对大规模分配支持异步处理模式
---
**📅 更新记录**
- 2025-01-03:完成连续分配逻辑实现
- 2025-01-03:创建优化说明文档
- 2025-01-03:修改排序逻辑,改为按房间编码(roomCode)和床位编码(bedCode)排序