• 二维装箱算法


    需求:把箱子装到车上

    /**

    • 策略上下文

    • 〈装箱工具〉

    • @author 27381

    • @version V1.0

    • @date 2020/12/5.
      */
      public class ContextStrategy extends Abstractloader {
      LoaderStrategy loaderStrategy;

      public ContextStrategy(LoaderStrategy p_loaderStrategy) {
      loaderStrategy = p_loaderStrategy;

      }

      public void build() {
      loaderStrategy.load(getSheet(), getTruck());
      }
      }

    /**

    • DESCRIPTION: 策略接口,如果以后要扩展其他装载策略,请添加实现此接口,添加策略。
    • Created by hdk on 2020/12/5.
    • @version V1.0
      */

    public interface LoaderStrategy {
    void load(XSSFSheet c_sheet, Truck c_truck);
    /**
    * POI合并单元格及期样式设置
    * @param sheet
    * @param box
    */
    default void PutBox(XSSFSheet sheet, Box box){
    XSSFRow row = sheet.getRow(box.getFirstRow());
    XSSFCell cell = row.getCell((short) box.getFirstCol());
    cell.setCellValue(box.getContent().replace("R","").replace("L",""));
    cell.getCellStyle().setAlignment(HorizontalAlignment.CENTER);
    cell.getCellStyle().setVerticalAlignment(VerticalAlignment.CENTER);

        final CellRangeAddress cellRangeAddress = new CellRangeAddress(box.getFirstRow(), box.getLastRow() - 1, box.getFirstCol(), box.getLastCol() - 1);
    
        RegionUtil.setBorderBottom(BorderStyle.THIN, cellRangeAddress, sheet);
        RegionUtil.setBorderLeft(BorderStyle.THIN, cellRangeAddress, sheet);
        RegionUtil.setBorderRight(BorderStyle.THIN, cellRangeAddress, sheet);
        RegionUtil.setBorderTop(BorderStyle.THIN, cellRangeAddress, sheet);
    
        cell.getCellStyle().setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());// 增加颜色  灰色
        cell.getCellStyle().setFillPattern(FillPatternType.SOLID_FOREGROUND);
    
        sheet.addMergedRegion(cellRangeAddress);
    }
    

    }

    /**

    • 〈装载抽象

    • 〈〉

    • @author hdk

    • @version V1.0

    • @date 2020/12/5.
      */
      abstract class Abstractloader {

      public Truck getTruck() {
      return truck;
      }

      public void setTruck(Truck truck) {
      this.truck = truck;
      }

      private Truck truck;

      public XSSFSheet getSheet() {
      return sheet;
      }

      public void setSheet(XSSFSheet sheet) {
      this.sheet = sheet;
      }

      XSSFSheet sheet;

    }

    **

    • 卡车

    • 〈〉

    • @author hdk

    • @version V1.0

    • @date 2020/12/5.
      */
      public class Truck {

      //宽
      private int width = 240;
      //长
      private int length = 1200;

      public int getWidth() {
      return width;
      }

      public int getLength() {
      return length;
      }

      public Truck(int p_width, int p_length) {
      width = p_width;
      length = p_length;
      }

      public List getBoxs() {
      return Boxs;
      }

      public Truck() {
      }

      private List Boxs = new ArrayList();

      public void put(Box box) {
      Boxs.add(box);
      }
      }

    /**

    • @author hdk

    • @version V1.0

    • @date 2020/12/5.
      */
      public class Box {
      //宽
      private int width;
      //长
      private int length;

      public int getWidth() {
      return width;
      }

      public int getLength() {
      return length;
      }

      public int getFirstRow() {
      return firstRow;
      }

      public int getLastRow() {
      return lastRow;
      }

      public int getFirstCol() {
      return firstCol;
      }

      public int getLastCol() {
      return lastCol;
      }

      private int firstRow;

      public void setFirstRow(int firstRow) {
      this.firstRow = firstRow;
      }

      public void setLastRow(int lastRow) {
      this.lastRow = lastRow;
      }

      public void setFirstCol(int firstCol) {
      this.firstCol = firstCol;
      }

      public void setLastCol(int lastCol) {
      this.lastCol = lastCol;
      }

      private int lastRow;
      private int firstCol;
      private int lastCol;

      public Box( int y,int x, String p_content) {
      width = y;
      length = x;
      content = p_content;
      // 240 * 1200
      }

      public String getContent() {
      return content;
      }

      public void setContent(String content) {
      this.content = content;
      }

      private String content;

      public int getCellCountY(){
      return width/10;
      }

      /**
      *

      • @return
        */
        public int getCellCountX(){
        return length/10;
        }

    }

    /**

    • 240*1200

    • 卡车装箱策略

    • @author hdk

    • @version V1.0

    • @date 2020/12/5.
      */
      public class TruckLoaderStrategy implements LoaderStrategy {

      @Override
      public void load(XSSFSheet c_sheet, Truck c_truck) {
      int y = c_truck.getWidth();//2401200 厘米 24120
      int x = c_truck.getLength();

       int firstRow = 19, firstCol = 11;
      
       for (int i = 0; i < c_truck.getBoxs().size(); ) {
           final Box box = c_truck.getBoxs().get(i);
      
           if (i == 0) {//第一个箱子
               box.setFirstRow(firstRow);
               box.setFirstCol(firstCol);
      
           } else {
               final Box preBox = c_truck.getBoxs().get(i - 1);
      
               box.setFirstRow(preBox.getLastRow());
               box.setFirstCol(preBox.getFirstCol());
               //判断列是否装满
               if (preBox.getLastRow() + box.getCellCountY() > (firstRow + (y / 10))) {
                   box.setFirstRow(firstRow);
      
                   int prepreCol = 0;
                   if (i - 2 >= 0) {//比较前面两个箱子,以最长的箱子为准,不然会导致箱子重叠
                       prepreCol = c_truck.getBoxs().get(i - 2).getLastCol();
                   }
                   int max = Math.max(preBox.getLastCol(), prepreCol);
                   box.setFirstCol(max);
               }
      
           }
      
           box.setLastRow(box.getCellCountY() + box.getFirstRow());
           box.setLastCol(box.getCellCountX() + box.getFirstCol());
      
           //只能放右边
           if (box.getContent().indexOf("R") > -1 && box.getFirstRow() > firstRow) {
               c_truck.getBoxs().set(i, c_truck.getBoxs().get(i + 1));
               c_truck.getBoxs().set(i + 1, box);
               continue;
           }
           //只能放左边
           if (box.getContent().indexOf("L") > -1 && box.getFirstRow() == firstRow) {
               if (i < c_truck.getBoxs().size()) {//最后一位不能调换
      
                   c_truck.getBoxs().set(i, c_truck.getBoxs().get(i + 1));
                   c_truck.getBoxs().set(i + 1, box);
                   continue;
      
               }
           }
      
           if (box.getLastCol() <= (11 + x / 10)) {//判断是否超过车长
               PutBox(c_sheet, box);
           }
           i++;
      
       }
      

      }

    }

    测试

    @Test
    public void testContextStrategy() {

        int width2 = 300, height2 = 300;
    
    
        String fileToBeRead = "D:\out\生成模板.xlsx"; // excel位置
        String fileToBeRead1 = "D:\out\生成模板1.xlsx"; // excel位置
        int coloum = 11; // 比如你要获取第1列
        try {
            XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(
                    fileToBeRead));
            XSSFSheet sheet = workbook.getSheet("Sheet2");
    

    // XSSFSheet sheet3 = workbook.cloneSheet(0,"Sheet3");
    Truck truck = new Truck(240, 1200);

            truck.put(new Box(150, 110,"1"));
            truck.put(new Box(110, 110,"2"));
            truck.put(new Box(130, 130,"3"));
            truck.put(new Box(130, 130,"4"));
            truck.put(new Box(110, 110,"5"));
            truck.put(new Box(150, 110,"6"));
            truck.put(new Box(90, 110,"7"));
            truck.put(new Box(200, 110,"8"));
            truck.put(new Box(120, 150,"9"));
            truck.put(new Box(120, 120,"10"));
    
            List<Box> Boxs = truck.getBoxs();
    
            final TruckLoaderStrategy truckLoaderStrategy = new TruckLoaderStrategy();
    
            ContextStrategy loaderStrategy = new ContextStrategy(truckLoaderStrategy);
            loaderStrategy.setSheet(sheet);
            loaderStrategy.setTruck(truck);
            loaderStrategy.build();
    
    
            FileOutputStream out = null;
            try {
                out = new FileOutputStream(fileToBeRead1);
                workbook.write(out);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    效果

  • 相关阅读:
    c++Primer再学习(1)
    c++Primer再学习练习Todo
    感悟(一)
    新目标《C++程序设计原理与实践》
    C++Primer再学习(4)
    开篇
    C++Primer再学习(3)
    C++实现的单例模式的解惑
    使用springboot缓存图片
    springboot h2 database
  • 原文地址:https://www.cnblogs.com/wolf12/p/14090329.html
Copyright © 2020-2023  润新知