二维装箱算法

需求:把箱子装到车上

/**

  • 策略上下文

  • 〈装箱工具〉

  • @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();//2401300 厘米 24130
    int x = c_truck.getLength();

     int firstRow = 19, firstCol = 11;
     int currentIndex = 0;
    
     for (int i = 0; i < c_truck.getBoxs().size(); ) {
         final Box box = c_truck.getBoxs().get(i);
         Box preBox=null;
         if (i == 0) {//第一个箱子
             box.setFirstRow(firstRow);
             box.setFirstCol(firstCol);
    
         } else {
             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) {
             int tempindex = i + 1 + currentIndex;
             if (tempindex < c_truck.getBoxs().size()) {
                 c_truck.getBoxs().set(i, c_truck.getBoxs().get(tempindex));
                 c_truck.getBoxs().set(tempindex, box);
                 currentIndex++;
                 continue;
             } else {
                 box.setFirstRow(firstRow);
                 box.setLastRow(box.getCellCountY() + box.getFirstRow());
                 box.setFirstCol(preBox.getLastCol());
                 box.setLastCol(box.getCellCountX() + box.getFirstCol());
             }
         }
         //只能放左边
         if (box.getContent().indexOf("L") > -1 && box.getFirstRow() == firstRow) {
             if (i < c_truck.getBoxs().size()) {//最后一位不能调换
    
                 int tempindex = i + 1 + currentIndex;
    
                 try {
                     if (tempindex < c_truck.getBoxs().size()) {
                         c_truck.getBoxs().set(i, c_truck.getBoxs().get(tempindex));
                         c_truck.getBoxs().set(tempindex, box);
                         currentIndex++;//依次往下获取
                         continue;
                     } else {
                         box.setFirstRow((firstRow + 24) - box.getCellCountY());
                         box.setLastRow(box.getCellCountY() + box.getFirstRow());
                     }
                 } catch (Exception e) {
    
                     e.printStackTrace();
                 }
    
             }
         }
         currentIndex = 0;
         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();
    }
}

效果

posted on 2020-12-05 17:22  wolf12  阅读(1075)  评论(0编辑  收藏  举报