提交修改

This commit is contained in:
zlwu committed 2025-08-13 08:55:04 +08:00
1 parent e25f1e7a1f
commit cf6387f8f7
2 files changed
+319 -79

No files matched your search

@@ -8,7 +8,7 @@
## 🎯 优化目标
将床位分配逻辑从**分散分配**调整为**连续分配**,确保同一学院的学生尽量分配在相邻的房间或同一房间内,提高宿舍管理效率。
将床位分配逻辑从**分散分配**调整为**房间优先分配**,采用四轮分配策略:优先分配完整房间,尽量避免混住,但确保所有床位100%分配利用,提高宿舍管理效率。
## 🔄 分配逻辑对比
@@ -24,16 +24,15 @@
结果:学院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个)
- 房间3:床位1-8 → 学院B(8个)
- 房间4:床位1-7 → 学院C(7个)
...
结果:每个学院的学生相对集中
结果:同一房间尽量安排同一学院学生,避免混住
```
## 🎯 分配示例
@@ -46,12 +45,26 @@
- 学院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(8个床位):学院A(床位1-8,完整房间)
房间2(8个床位):学院A(床位1-2,同学院补充)
房间3(8个床位):学院B(床位1-8,完整房间)
房间4(8个床位):学院C(床位1-7)+ 空余1个床位
剩余:学院D(7个)→ 需要新增房间或调整分配
```
### 算法优势对比
**🔴 避免的问题(连续分配):**
```
房间2:学院A(床位1-2)+ 学院B(床位3-8)← 混住
房间3:学院B(床位1-2)+ 学院C(床位3-8)← 混住
```
**✅ 实现的效果(房间优先):**
```
房间2:学院A(床位1-2)← 同学院
房间3:学院B(床位1-8)← 完整房间
```
## 🔧 技术实现
@@ -82,73 +95,181 @@ List<XgDormBed> sortedBeds = beds.stream()
.collect(java.util.stream.Collectors.toList());
```
#### 2. 连续分配算法
#### 2. 房间分组与优先分配算法
```java
int currentBedIndex = 0; // 当前分配到的床位索引
// 按房间分组床位
Map<Long, List<XgDormBed>> bedsByRoom = sortedBeds.stream()
.collect(java.util.stream.Collectors.groupingBy(XgDormBed::getRoomId));
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);
// 创建分配记录...
// 房间使用状态跟踪
int[] roomUsage = new int[sortedRoomIds.size()];
Map<Integer, Long> roomCollegeMap = new HashMap<>();
for (每个学院) {
// 第一轮:优先分配完整房间
for (每个房间) {
if (房间空闲 && 学生数量 >= 房间容量) {
分配整个房间给当前学院;
}
}
// 更新当前床位索引
currentBedIndex += studentCount;
// 第二轮:补充分配到已有该学院学生的房间
for (每个房间) {
if (房间有剩余床位 && 房间已分配给当前学院) {
分配剩余床位给当前学院;
}
}
// 第三轮:分配到空闲房间(避免混住)
for (每个房间) {
if (房间有剩余床位 && 房间完全空闲) {
分配床位给当前学院;
标记房间为当前学院所有;
}
}
// 第四轮:确保100%分配(允许混住)
for (每个房间) {
if (房间有剩余床位) {
分配剩余床位给当前学院;
记录混住警告信息;
}
}
}
```
#### 3. 辅助分配方法
```java
/**
* 将床位分配给学院的辅助方法
*/
private void allocateBedsToCollege(List<XgDormBed> beds, Long collegeId,
List<XgDormBedStudent> allocationRecords,
XgDormBuilding building, Long buildingId, Date now) {
for (XgDormBed bed : beds) {
XgDormBedStudent allocation = new XgDormBedStudent();
allocation.setCollegeId(collegeId);
allocation.setBedId(bed.getId());
allocation.setRoomId(bed.getRoomId());
// ... 其他字段设置
allocationRecords.add(allocation);
}
}
```
### 关键优化点
#### 1. 索引管理
- **原逻辑**: 复杂的房间遍历和床位查找
- **新逻辑**: 简单的索引递增,O(1)时间复杂度
#### 1. 房间优先策略
- **原逻辑**: 连续分配导致学院混住同一房间
- **新逻辑**: 三轮分配策略,优先保证房间完整性
#### 2. 内存效率
- **原逻辑**: 需要维护房间分组Map和动态删除操作
- **新逻辑**: 一次性排序,线性访问,内存占用更少
#### 2. 避免混住机制
- **原逻辑**: 不考虑房间边界,容易产生混住
- **新逻辑**: 尽量控制房间分配,优先同学院,必要时允许混住确保100%分配
#### 3. 分配可预测性
- **原逻辑**: 分配结果难以预测
- **新逻辑**: 分配结果完全可预测,便于调试和验证
#### 3. 状态跟踪优化
- **原逻辑**: 简单的床位索引递增
- **新逻辑**: 房间使用状态和学院映射跟踪,更精确控制
#### 4. 排序优化
#### 4. 分配策略层次化
- **原逻辑**: 单一的连续分配模式
- **新逻辑**: 四轮分配(完整房间→同学院补充→空闲房间→混住补充),更智能且确保100%利用
#### 5. 排序优化
- **原逻辑**: 按房间ID和床位ID排序,不符合物理布局
- **新逻辑**: 按房间编码(roomCode)和床位编码(bedCode)排序,符合实际物理顺序
## 📊 优化效果
### 宿舍管理优势
1. **集中管理**: 每个学院的学生相对集中,便于管理员统一管理
2. **减少跨楼层**: 学生活动和管理主要在相邻房间,减少跨楼层流动
3. **便于统计**: 学院相关的宿舍统计更加方便
1. **避免混住**: 同一房间尽量安排同一学院学生,减少管理复杂度
2. **房间完整性**: 优先分配完整房间,便于学院统一管理
3. **清晰归属**: 房间与学院的对应关系更加明确
4. **便于统计**: 学院相关的宿舍统计更加方便和准确
### 学生体验优势
1. **同学院聚集**: 同学院学生住宿相对集中,便于学习和生活交流
2. **减少陌生感**: 周边多为同学院学生,归属感更强
3. **便于组织活动**: 学院活动组织更加便利
1. **室友同学院**: 同房间室友来自同一学院,便于学习和生活交流
2. **减少冲突**: 避免不同学院学生因管理差异产生的冲突
3. **归属感强**: 同学院聚集居住,增强学院归属感
4. **便于组织活动**: 学院活动组织更加便利
### 系统性能优势
1. **算法效率**: 时间复杂度从O(n²)降低到O(n log n)
2. **内存占用**: 减少临时数据结构,内存使用更高效
3. **代码维护**: 逻辑更清晰,便于理解和维护
## 🎯 四轮分配策略详解
新算法采用智能的四轮分配模式,平衡房间管理和床位利用率:
### 🥇 第一轮:完整房间优先
- 优先给学院分配完整房间(8个床位/房间)
- 确保房间完整性,便于管理
- **目标**: 最大化房间完整分配
### 🥈 第二轮:同学院补充
- 将剩余学生安排到已有该学院学生的房间
- 保持房间内学院统一性
- **目标**: 避免在已有学院房间产生混住
### 🥉 第三轮:空闲房间分配
- 分配到完全空闲的房间
- 尽量避免与其他学院产生混住
- **目标**: 维持房间学院纯度
### 🏆 第四轮:确保100%分配
- **关键改进**:分配剩余床位到任何有空床的房间
- 允许混住,但确保所有学生都有床位
- 记录混住情况,便于后续管理
- **目标**: 床位资源充分利用,无浪费
### 📊 分配策略对比
#### 🔴 纯粹避免混住策略(理想但不现实):
```
优点:房间管理简单
缺点:可能导致床位浪费,学生无床位分配
场景:床位充足时可行
```
#### ✅ 四轮平衡策略(实用且高效):
```
优点:既尽量避免混住,又确保100%分配
缺点:少量房间可能产生混住
场景:适用于床位紧张的实际情况
```
## 🧪 测试验证
### 测试用例1:标准分配
### 测试用例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个)
预期输出(房间优先策略):
- 房间1:学院A(全部8个,完整房间)
- 房间2:学院A(2个,同学院补充)
- 房间3:学院B(全部8个,完整房间)
- 房间4:学院C(7个)+ 空余1个
优势:避免了学院混住,每个房间最多只有一个学院
```
### 测试用例2:混住对比验证
```
连续分配结果(会产生混住):
- 房间1:学院A(8个)
- 房间2:学院A(2个)+ 学院B(6个)← 混住
- 房间3:学院B(2个)+ 学院C(6个)← 混住
- 房间4:学院C(1个)+ 学院D(7个)← 混住
房间优先分配结果(避免混住):
- 房间1:学院A(8个)
- 房间2:学院A(2个)← 同学院
- 房间3:学院B(8个)
- 房间4:学院C(7个)+ 学院D(1个)
- 需要:为学院D新增房间分配剩余6个床位
```
### 测试用例2:边界情况
@@ -192,4 +313,8 @@ for (int collegeIndex = 0; collegeIndex < bo.getCollegeIds().size(); collegeInde
**📅 更新记录**
- 2025-01-03:完成连续分配逻辑实现
- 2025-01-03:创建优化说明文档
- 2025-01-03:修改排序逻辑,改为按房间编码(roomCode)和床位编码(bedCode)排序
- 2025-01-03:修改排序逻辑,改为按房间编码(roomCode)和床位编码(bedCode)排序
- 2025-01-03:重大升级!将连续分配改为房间优先分配,避免学院混住问题
- 2025-01-03:实现三轮分配策略(完整房间→同学院补充→空闲房间)
- 2025-01-03:新增allocateBedsToCollege辅助方法,提高代码复用性
- 2025-01-03:关键升级!新增第四轮分配,确保100%床位利用率,平衡避免混住与资源充分利用