|
|
@@ -383,7 +383,30 @@ public class GameEventGroupServiceImpl implements IGameEventGroupService {
|
|
|
log.warn("每组人数({})超过道数({}),将限制为道数", personsPerGroup, groupInfo.getTrackNum());
|
|
|
personsPerGroup = groupInfo.getTrackNum();
|
|
|
}
|
|
|
- for (int track = 1; track <= personsPerGroup; track++) {
|
|
|
+
|
|
|
+ int personsPerGroupInt = personsPerGroup.intValue();
|
|
|
+
|
|
|
+ // 实际可用的道次数量
|
|
|
+ int actualTrackNum = groupInfo.getTrackNum().intValue();
|
|
|
+
|
|
|
+ // 动态生成最优分配顺序:从中间开始,按照空位规则(空8道>空1道>空7道>空2道)
|
|
|
+ List<Integer> optimalTrackOrder = generateOptimalTrackOrder(actualTrackNum);
|
|
|
+
|
|
|
+ // 根据实际道数和需要人数调整分配顺序
|
|
|
+ List<Integer> tracksToAssign = new ArrayList<>();
|
|
|
+ for (Integer track : optimalTrackOrder) {
|
|
|
+ if (track <= actualTrackNum && tracksToAssign.size() < personsPerGroupInt) {
|
|
|
+ tracksToAssign.add(track);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保我们只分配需要的人数,多余的道次留空
|
|
|
+ if (tracksToAssign.size() > personsPerGroupInt) {
|
|
|
+ tracksToAssign = tracksToAssign.subList(0, personsPerGroupInt);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按优化的道次顺序分配运动员
|
|
|
+ for (Integer track : tracksToAssign) {
|
|
|
// 寻找可用的运动员
|
|
|
GameAthleteVo selectedAthlete = null;
|
|
|
int athleteIndex = 0;
|
|
|
@@ -559,4 +582,60 @@ public class GameEventGroupServiceImpl implements IGameEventGroupService {
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 动态生成最优跑道分配顺序
|
|
|
+ * 根据任意道数,先填所有组的中间道,然后填比中间道小1的道,再填比中间道大1的道,以此类推
|
|
|
+ * @param totalTracks 总道数
|
|
|
+ * @return 最优分配顺序的道次列表
|
|
|
+ */
|
|
|
+ private List<Integer> generateOptimalTrackOrder(int totalTracks) {
|
|
|
+ List<Integer> result = new ArrayList<>();
|
|
|
+ if (totalTracks <= 0) {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果是1道,直接返回
|
|
|
+ if (totalTracks == 1) {
|
|
|
+ result.add(1);
|
|
|
+ log.debug("为{}道生成的最优跑道顺序: {}", totalTracks, result);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算中间位置
|
|
|
+ int middle = totalTracks / 2 + 1;
|
|
|
+
|
|
|
+ // 从中间向两侧展开,先左后右(小的道次优先)
|
|
|
+ // 使用队列来按层序存储道次
|
|
|
+ Queue<Integer> queue = new LinkedList<>();
|
|
|
+ Set<Integer> visited = new HashSet<>();
|
|
|
+
|
|
|
+ // 将中间位置作为起点加入队列
|
|
|
+ queue.offer(middle);
|
|
|
+ visited.add(middle);
|
|
|
+
|
|
|
+ while (!queue.isEmpty()) {
|
|
|
+ int current = queue.poll();
|
|
|
+ result.add(current);
|
|
|
+
|
|
|
+ // 先添加比当前道小1的道次(如果存在且未访问)
|
|
|
+ int left = current - 1;
|
|
|
+ if (left >= 1 && !visited.contains(left)) {
|
|
|
+ queue.offer(left);
|
|
|
+ visited.add(left);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 再添加比当前道大1的道次(如果存在且未访问)
|
|
|
+ int right = current + 1;
|
|
|
+ if (right <= totalTracks && !visited.contains(right)) {
|
|
|
+ queue.offer(right);
|
|
|
+ visited.add(right);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 记录生成的跑道顺序
|
|
|
+ log.debug("为{}道生成的最优跑道顺序: {}", totalTracks, result);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
}
|