AssignMethod.java 12.2 KB
package com.neotel.webbox.capacitynew.method;


import com.neotel.webbox.capacitynew.bean.BoxData;
import com.neotel.webbox.capacitynew.bean.BoxResult;
import com.neotel.webbox.capacitynew.bean.ReelData;
import com.neotel.webbox.capacitynew.bean.RequestItem;
import com.neotel.webbox.capacitynew.box.Box;
import com.neotel.webbox.capacitynew.box.Column;
import com.neotel.webbox.capacitynew.box.SlotUnit;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import static com.neotel.webbox.capacitynew.method.BasicMethod.*;

@Slf4j
public class AssignMethod {
    public static BoxResult averageCapacityToBox(BoxData boxData, List<RequestItem> requestList) {
        //最大的压紧张开高度
        int maxPressHeight = 0;
        //剩余放置料盘的总高度
        int totalRemainNeedHeight = 0;
        //是否只有一种料需求
        boolean onlyOneRequest = requestList.size() == 1;
        for (RequestItem requestItem : requestList) {
            ReelData rd = requestItem.getReelData();
            //纯放此料盘料仓容量
            int pureBoxCapacity = boxData.getBoxPureSizeCapacity(requestItem.getReelData());
            int pureBoxCount = requestItem.getNum() / pureBoxCapacity;
            int remainNum = requestItem.getNum() % pureBoxCapacity;
            if (onlyOneRequest) {
                log.info("只有一种规格物料,使用纯料仓");
                if (remainNum > 0) {
                    remainNum = 0;
                    pureBoxCount = pureBoxCount + 1;
                }
            }
            requestItem.setPureBoxCount(pureBoxCount);
            requestItem.setRemainNum(remainNum);
            log.info("料盘[" + rd.getReelSizeStr() + "]总需求:" + requestItem.getNum() + "需要纯料仓" + pureBoxCount + "个,每个料仓可放:" + pureBoxCapacity + "盘,剩余:" + remainNum + "盘需要放到混合仓");

            totalRemainNeedHeight = totalRemainNeedHeight + requestItem.getRemainNeedHeight();
            if (rd.getPressHeight() > maxPressHeight) {
                maxPressHeight = rd.getPressHeight();
            }
        }

        List<Box> mixBoxList = new ArrayList<>();
        //判断是否需要混合仓
        if (!onlyOneRequest) {
            //获取到料仓可用数量
            int mixBoxTotalValidHeight = boxData.getTotalValidHeight(maxPressHeight, requestList);
            //估算混合仓数量
            Float estimateMixBoxCount =   totalRemainNeedHeight / (mixBoxTotalValidHeight * 1.1f);
            int mixBoxCount = estimateMixBoxCount.intValue();
            if (estimateMixBoxCount - mixBoxCount > 0) {
                mixBoxCount = mixBoxCount + 2;
            }
            log.info("剩余物料需要 " + mixBoxCount + " 个混合仓");
            for (int i = 1; i <= mixBoxCount; i++) {
                mixBoxList.add(Box.newBox(boxData, requestList, maxPressHeight));
            }
            //从需求大到小排序,优先满足大需求
            requestList.sort((o1, o2) -> o2.getNum() - o1.getNum());
            //正常列可用高度
            int columnValidHeight = boxData.getColumnValidHeight(maxPressHeight);
            //标准列
            Column column = new Column(columnValidHeight);
            //先每列均分,如果有剩余,安排到料仓口的上下位置
            for (RequestItem requestItem : requestList) {
                int totalRemainNum = requestItem.getRemainNum();  //剩余料盘的数量
                int totalColumn = mixBoxList.size() * boxData.getColumnCount(); //标准列总数
                int countPerColumn = totalRemainNum / totalColumn; //每列填充的数量
                int assignReelCount = 0;
                if (requestItem.getReelData().is7Reel()) {
                    //7寸盘会填充,这里不需要填充
                    countPerColumn = countPerColumn / 2 * 2;
                }
                SlotUnit slotUnit = getValidSlotUnit(countPerColumn, requestItem.getReelData(), column.getRemainHeight());
                slotUnit = column.addSlotUnit(slotUnit);
                //为null表示一个没填充进去, 不为null可能只填充了一部分
                if (slotUnit != null) {
                    assignReelCount = slotUnit.getReelCount() * totalColumn;
                    log.info("添加" + assignReelCount + "个" + requestItem.getReelSizeStr() + "料盘到标准列,每列" + slotUnit.getReelCount() + "个料盘");
                }
                //没有安排的料盘,安排到特殊列
                int notArrangedNum = totalRemainNum - assignReelCount;
                for (Box box : mixBoxList) {
                    Map<String, Column> specialColumnMap = box.getSpecialColumnMap();
                    if (specialColumnMap != null && specialColumnMap.size() > 0) {
                        for (Map.Entry<String, Column> entry : specialColumnMap.entrySet()) {
                            SlotUnit singleSpecialColumnAddUnit = getValidSlotUnit(notArrangedNum, requestItem.getReelData(), entry.getValue().getRemainHeight());
                            singleSpecialColumnAddUnit = entry.getValue().addSlotUnit(singleSpecialColumnAddUnit);
                            if (singleSpecialColumnAddUnit != null) {
                                log.info("添加" + singleSpecialColumnAddUnit.getReelCount() + "个" + requestItem.getReelSizeStr() + "料盘到" + entry.getKey());
                                notArrangedNum = notArrangedNum - singleSpecialColumnAddUnit.getReelCount();
                            }
                        }
                    }

                    Map<String, Column> specialColumnUpMap = box.getSpecialColumnUpMap();
                    if (specialColumnUpMap != null && specialColumnUpMap.size() > 0) {
                        for (Map.Entry<String, Column> entry : specialColumnUpMap.entrySet()) {
                            SlotUnit singleSpecialColumnUpAddUnit = getValidSlotUnit(notArrangedNum, requestItem.getReelData(), entry.getValue().getRemainHeight());
                            singleSpecialColumnUpAddUnit = entry.getValue().addSlotUnit(singleSpecialColumnUpAddUnit);
                            if (singleSpecialColumnUpAddUnit != null) {
                                log.info("添加" + singleSpecialColumnUpAddUnit.getReelCount() + "个" + requestItem.getReelSizeStr() + "料盘到" + entry.getKey());
                                notArrangedNum = notArrangedNum - singleSpecialColumnUpAddUnit.getReelCount();
                            }
                        }
                    }
                }
                requestItem.setRemainNum(notArrangedNum);
                if (notArrangedNum > 0) {
                    //还有未安排的料盘,如果标准列有位置就添加进去,如果没有那就是放不下了
                    log.warn("" + notArrangedNum + "个" + requestItem.getReelSizeStr() + "无处安放");
                }
            }

            //填充料盘(需求数量最多的)
            RequestItem fillRequestItem = null;
            //用剩余的空间去放还未满足的料盘
            for (RequestItem requestItem : requestList) {
                if (fillRequestItem == null || requestItem.getNum() > fillRequestItem.getNum()) {
                    fillRequestItem = requestItem;
                }
                int remainNum = requestItem.getRemainNum();
                int addCount = fillToColumn(column, remainNum, requestItem.getReelData());
                if (addCount > 0) {
                    remainNum = remainNum - addCount;
                    requestItem.setRemainNum(remainNum);
                    log.info("添加" + addCount + "个" + requestItem.getReelSizeStr() + "料盘到标准列,无处安放料盘数为:" + remainNum);
                }
                if (remainNum > 0) {
                    for (Box box : mixBoxList) {
                        Map<String, Column> specialColumnMap = box.getSpecialColumnMap();
                        if (specialColumnMap != null && specialColumnMap.size() > 0) {
                            if (specialColumnMap != null && specialColumnMap.size() > 0) {
                                for (Map.Entry<String, Column> entry : specialColumnMap.entrySet()) {
                                    addCount = fillToColumn(entry.getValue(), remainNum, requestItem.getReelData());
                                    if (addCount > 0) {
                                        remainNum = remainNum - addCount;
                                        requestItem.setRemainNum(remainNum);
                                        log.info("添加" + addCount + "个" + requestItem.getReelSizeStr() + "料盘到" + entry.getKey() + ",无处安放料盘数为:" + remainNum);
                                    }
                                }
                            }
                        }

                        Map<String, Column> specialColumnUpMap = box.getSpecialColumnUpMap();
                        if (specialColumnUpMap != null && specialColumnUpMap.size() > 0) {
                            if (specialColumnUpMap != null && specialColumnUpMap.size() > 0) {
                                for (Map.Entry<String, Column> entry : specialColumnUpMap.entrySet()) {
                                    addCount = fillToColumn(entry.getValue(), remainNum, requestItem.getReelData());
                                    if (addCount > 0) {
                                        remainNum = remainNum - addCount;
                                        requestItem.setRemainNum(remainNum);
                                        log.info("添加" + addCount + "个" + requestItem.getReelSizeStr() + "料盘到" + entry.getKey() + ",无处安放料盘数为:" + remainNum);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //进行填充
            int fillCount = fillToColumn(column, -1, fillRequestItem.getReelData());
            if (fillCount > 0) {
                log.info("填充" + fillCount + "个" + fillRequestItem.getReelSizeStr() + "料盘到标准列,标准列空闲高度为:" + column.getRemainHeight());
            } else {
                log.info("标准列空闲高度为: " + column.getRemainHeight() + " ");
            }
            for (Box box : mixBoxList) {
                Map<String, Column> specialColumnUpMap = box.getSpecialColumnUpMap();
                if (specialColumnUpMap != null && specialColumnUpMap.size() > 0) {
                    for (Map.Entry<String, Column> entry : specialColumnUpMap.entrySet()) {
                        fillCount = fillToColumn(entry.getValue(), -1, fillRequestItem.getReelData());
                        if (fillCount > 0) {
                            log.info("填充" + fillCount + "个" + fillRequestItem.getReelSizeStr() + "料盘到" + entry.getKey() + "上方列,其空闲高度为:" + entry.getValue().getRemainHeight());
                        } else {
                            log.info("门口上方列空闲高度为:" + entry.getValue().getRemainHeight() + " ");
                        }
                    }
                }

                Map<String, Column> specialColumnMap = box.getSpecialColumnMap();
                if (specialColumnMap != null && specialColumnUpMap.size() > 0) {
                    for (Map.Entry<String, Column> entry : specialColumnMap.entrySet()) {
                        fillCount = fillToColumn(entry.getValue(), -1, fillRequestItem.getReelData());
                        if (fillCount > 0) {
                            log.info("填充" + fillCount + "个" + fillRequestItem.getReelSizeStr() + "料盘到" + entry.getKey() + ",其空闲高度为:" + entry.getValue().getRemainHeight());
                        } else {
                            log.info("门口上方列空闲高度为:" + entry.getValue().getRemainHeight() + " ");
                        }
                    }
                }
            }
            for (Box box : mixBoxList) {
                box.setColumn(column);
                box.setColumnCount(boxData.getColumnCount());
            }
        }
        return getBoxResult(requestList, boxData, mixBoxList);
    }
}