New file |
| | |
| | | package com.zy.acs.manager.manager.utils; |
| | | |
| | | import com.zy.acs.manager.manager.entity.Action; |
| | | import com.zy.acs.manager.manager.enums.ActionTypeType; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class ActionSorter { |
| | | |
| | | /** |
| | | * 对传入的 actionList 进行排序或重新排列 |
| | | * 规则: |
| | | * 1. 寻找第一个 ReadyTakeFromAgvSite 的动作(取货动作)。 |
| | | * 2. 如果找到,则寻找最后一个 TurnCorner 的动作。 |
| | | * - 若找到 TurnCorner,则在其后插入取货动作(并将取货动作的 code 替换为 TurnCorner 动作的 code)。 |
| | | * - 若没找到 TurnCorner,则将取货动作放在列表最前面(同时替换为第一个动作的 code)。 |
| | | * 3. 如果没有 ReadyTakeFromAgvSite,则直接返回原列表。 |
| | | * |
| | | * @param actionList 原始动作列表 |
| | | * @return 排序后的动作列表 |
| | | */ |
| | | public List<Action> optimizeSort(List<Action> actionList) { |
| | | if (actionList == null || actionList.isEmpty()) { |
| | | return actionList; |
| | | } |
| | | |
| | | // 获取关键信息 |
| | | final long readyTakeFromAgvSite = ActionTypeType.ReadyTakeFromAgvSite.val(); |
| | | final long readyReleaseToAgvSite = ActionTypeType.ReadyReleaseToAgvSite.val(); |
| | | final long turnCorner = ActionTypeType.TurnCorner.val(); |
| | | |
| | | // 找到第一个 readyTakeFromAgvSite 动作的下标 |
| | | int takeFromIdx = findFirstActionIndex(actionList, readyTakeFromAgvSite); |
| | | if (takeFromIdx == -1) { |
| | | // 如果没有取货动作,直接返回原列表 |
| | | return actionList; |
| | | } |
| | | |
| | | // 找到最后一个 readyReleaseToAgvSite 动作的下标 |
| | | int releaseToAgvSiteIdx = findLastActionIndex(actionList, readyReleaseToAgvSite); |
| | | // 如果同时存在 readyTakeFromAgvSite 和 readyReleaseToAgvSite,说明 取货 - 放货 肯定是在一个地面码上,这时候没必要再调整位置 |
| | | if (releaseToAgvSiteIdx != -1) { |
| | | return actionList; |
| | | } |
| | | |
| | | // 找到最后一个 turnCorner 动作的下标 |
| | | int turnCornerIdx = findLastActionIndex(actionList, turnCorner); |
| | | |
| | | // 根据是否找到 turnCorner 来选择不同的重新排序逻辑 |
| | | if (turnCornerIdx == -1) { |
| | | return reorderWithoutTurnCorner(actionList, takeFromIdx); |
| | | } else { |
| | | return reorderWithTurnCorner(actionList, takeFromIdx, turnCornerIdx); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 如果没有找到 TurnCorner,则将取货动作放到列表最前面(并使用原来第一个动作的 code) |
| | | */ |
| | | private List<Action> reorderWithoutTurnCorner(List<Action> actionList, int takeFromIdx) { |
| | | List<Action> sortedList = new ArrayList<>(actionList.size()); |
| | | Action takeFromAction = actionList.get(takeFromIdx); |
| | | |
| | | for (int i = 0; i < actionList.size(); i++) { |
| | | // 在处理第一个元素之前,先把取货动作加进去 |
| | | if (i == 0) { |
| | | // 用第一个动作的 code 替换取货动作 |
| | | takeFromAction.setCode(actionList.get(0).getCode()); |
| | | sortedList.add(takeFromAction); |
| | | } |
| | | // 跳过取货动作本身 |
| | | if (i == takeFromIdx) { |
| | | continue; |
| | | } |
| | | // 加入原动作 |
| | | sortedList.add(actionList.get(i)); |
| | | } |
| | | return sortedList; |
| | | } |
| | | |
| | | /** |
| | | * 如果找到 TurnCorner,则在 turnCorner 动作后插入取货动作(并使用 turnCorner 的 code) |
| | | */ |
| | | private List<Action> reorderWithTurnCorner(List<Action> actionList, int takeFromIdx, int turnCornerIdx) { |
| | | // 拷贝一份,准备重排 |
| | | List<Action> sortedList = new ArrayList<>(actionList.size()); |
| | | Action takeFromAction = actionList.get(takeFromIdx); |
| | | |
| | | for (int i = 0; i < actionList.size(); i++) { |
| | | // 跳过原先的取货动作 |
| | | if (i == takeFromIdx) { |
| | | continue; |
| | | } |
| | | // 先将当前动作加到列表 |
| | | Action curr = actionList.get(i); |
| | | sortedList.add(curr); |
| | | |
| | | // 若当前动作是 turnCorner 动作,则替换取货动作 code 并插入 |
| | | if (i == turnCornerIdx) { |
| | | takeFromAction.setCode(curr.getCode()); |
| | | sortedList.add(takeFromAction); |
| | | } |
| | | } |
| | | return sortedList; |
| | | } |
| | | |
| | | /** |
| | | * 在 actionList 中找到第一个指定 actionType 的下标 |
| | | */ |
| | | private int findFirstActionIndex(List<Action> actionList, long actionType) { |
| | | for (int i = 0; i < actionList.size(); i++) { |
| | | if (actionList.get(i).getActionType().equals(actionType)) { |
| | | return i; |
| | | } |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | /** |
| | | * 在 actionList 中找到最后一个指定 actionType 的下标 |
| | | */ |
| | | private int findLastActionIndex(List<Action> actionList, long actionType) { |
| | | int index = -1; |
| | | for (int i = 0; i < actionList.size(); i++) { |
| | | if (actionList.get(i).getActionType().equals(actionType)) { |
| | | index = i; |
| | | } |
| | | } |
| | | return index; |
| | | } |
| | | |
| | | } |