AssignMethod1.java 9.2 KB
package com.neotel.webbox.capacity.method;

import com.neotel.webbox.capacity.bean.*;
import com.neotel.webbox.capacity.box.Box;
import com.neotel.webbox.capacity.box.Column;
import com.neotel.webbox.capacity.box.SlotUnit;
import com.neotel.webbox.capacity.method.BasicMethod;
import lombok.extern.slf4j.Slf4j;

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


/**
 * 平均分配到每台料仓
 */
@Slf4j
public class AssignMethod1 extends BasicMethod {

    public static BoxResult averageAssignToBox(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);
            //估算混合仓数量
            Float estimateMixBoxCount = 1.0f * totalRemainNeedHeight / mixBoxTotalValidHeight;
            int mixBoxCount = estimateMixBoxCount.intValue();
            if(estimateMixBoxCount - mixBoxCount > 0){
                mixBoxCount = mixBoxCount + 1;
            }
            log.info("剩余物料需要 " + mixBoxCount +" 个混合仓");
            for(int i = 1; i<= mixBoxCount; i++){
                mixBoxList.add(Box.newBox(boxData,maxPressHeight));
            }

            //从需求大到小排序,优先满足大需求
            requestList.sort(new Comparator<RequestItem>() {
                @Override
                public int compare(RequestItem o1, RequestItem o2) {
                    return 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) {
                    Column doorDown = box.getDoorDown();
                    SlotUnit doorDownAddUnit = getValidSlotUnit(notArrangedNum, requestItem.getReelData(), doorDown.getRemainHeight());
                    doorDownAddUnit = doorDown.addSlotUnit(doorDownAddUnit);
                    if(doorDownAddUnit != null){
                        log.info("添加"+doorDownAddUnit.getReelCount()+"个"+ requestItem.getReelSizeStr()+"料盘到门口下方列");
                        notArrangedNum = notArrangedNum - doorDownAddUnit.getReelCount();
                    }

                    Column doorUp = box.getDoorUp();
                    SlotUnit doorUpAddUnit = getValidSlotUnit(notArrangedNum, requestItem.getReelData(), doorUp.getRemainHeight());
                    doorUpAddUnit = doorUp.addSlotUnit(doorUpAddUnit);
                    if(doorUpAddUnit != null){
                        log.info("添加"+doorUpAddUnit.getReelCount()+"个"+ requestItem.getReelSizeStr()+"料盘到门口上方列");
                        notArrangedNum = notArrangedNum - doorUpAddUnit.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) {
                        addCount = fillToColumn(box.getDoorUp(),remainNum,requestItem.getReelData());
                        if(addCount > 0){
                            remainNum = remainNum - addCount;
                            requestItem.setRemainNum(remainNum);
                            log.info("添加"+addCount+"个"+ requestItem.getReelSizeStr()+"料盘到门口上方列,无处安放料盘数为:" + remainNum);
                        }
                        addCount = fillToColumn(box.getDoorDown(),remainNum,requestItem.getReelData());
                        if(addCount > 0){
                            remainNum = remainNum - addCount;
                            requestItem.setRemainNum(remainNum);
                            log.info("添加"+addCount+"个"+ requestItem.getReelSizeStr()+"料盘到门口下方列,无处安放料盘数为:" + 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) {
                fillCount = fillToColumn(box.getDoorUp(),-1,fillRequestItem.getReelData());
                if(fillCount > 0){
                    log.info("填充"+fillCount+"个"+ fillRequestItem.getReelSizeStr()+"料盘到门口上方列,其空闲高度为:" + box.getDoorUp().getRemainHeight());
                }else{
                    log.info("门口上方列空闲高度为:" + box.getDoorUp().getRemainHeight()+" ");
                }
                fillCount = fillToColumn(box.getDoorDown(),-1,fillRequestItem.getReelData());
                if(fillCount > 0){
                    log.info("填充"+fillCount+"个"+ fillRequestItem.getReelSizeStr()+"料盘到门口下方列,其空闲高度为:" + box.getDoorDown().getRemainHeight());
                }else{
                    log.info("门口下方列空闲高度为:" + box.getDoorDown().getRemainHeight()+" ");
                }
            }
            for (Box box : mixBoxList) {
                box.setColumn(column);
                box.setColumnCount(boxData.getColumnCount());
            }
        }



        return getBoxResult(requestList,boxData,mixBoxList);

    }
}