1
\$\begingroup\$

I needed to make a freight calculator and had to solve a bin packing problem. I utilized a github package.

Basically with the help of my stack overflow question I made a class Method that

  • Splits an array of packable items into the number of largest boxes that those items can fit into
  • Splits the the item array into that number of items,
  • Goes through each large box and tries to fit it into smaller boxes, if it does it will repack into the smaller container and the container will be in the results Container array

public class PackingService {

    private List<Product> productsRequest;
    private ArrayList<BoxItem> productsToPack;
    private Map<Integer,ArrayList<BoxItem>> productSetsMap; 
    private Map<Integer,Container> packedContainerMap;

    public PackingService(List<Product> products) 
    {
        //containers = SetContainers();
        this.productsRequest = products;
        this.productSetsMap = new HashMap<Integer, ArrayList<BoxItem>>();
        this.packedContainerMap = new HashMap<Integer, Container>();
    }

    public ArrayList<Container> PackItems()
    {
        ArrayList<Container> packingResults = new ArrayList<Container>();
        PrepareProductsToPack(this.productsRequest);
        ArrayList<ArrayList<BoxItem>> productSetsToPack = splitProductSet(productsToPack, getInitBoxCount(productsToPack));
        int hashMapId = 0;
        for(int i = productSetsToPack.size()-1; i >= 0; i--)
        {
            ArrayList<BoxItem> itemsToPack = productSetsToPack.get(i);
            productSetsMap.put(hashMapId, itemsToPack);
            pack(itemsToPack, hashMapId, 5); //pack largest sized box
            ++hashMapId;
        }; 

        for (Map.Entry<Integer, Container> entry : packedContainerMap.entrySet()) {
            int containerKey = entry.getKey();
            Container packedContainer = entry.getValue();
            int smallestBoxSize = getSmallestBox(productSetsMap.get(containerKey), Integer.parseInt(packedContainer.getName()));
            packingResults.add(pack(productSetsMap.get(containerKey), smallestBoxSize));
        }
        return packingResults;
    }


    private int getInitBoxCount(ArrayList<BoxItem> itemsToPack)
    {
        if(doProductsFit(itemsToPack, 5) == false)
        {
            ArrayList<BoxItem> temp1 = new ArrayList<BoxItem>();
            ArrayList<BoxItem> temp2 = new ArrayList<BoxItem>();

            for(int x = 0; x < itemsToPack.size(); x++)
            {
               if(x > itemsToPack.size() / 2)
               {
                   temp1.add(itemsToPack.get(x));
               }
               else
               {
                   temp2.add(itemsToPack.get(x));
               }
            }
            return getInitBoxCount(temp1) + getInitBoxCount(temp2);
        }

        return 1;
    }

    private int getSmallestBox(ArrayList<BoxItem> items, int boxsize)
    {
        if(doProductsFit(items, boxsize -1) != false)
        {
            if(boxsize == 1)
                return boxsize;
            return getSmallestBox(items, boxsize -1);
        }
        else
            return boxsize;
    }

    private boolean doProductsFit(ArrayList<BoxItem> products, int boxsize)
    { 
        try
        {
            ArrayList<Container> testContainers = new ArrayList<Container>();
            testContainers.add(GetContainer(boxsize));
            Packager testPacker = new LargestAreaFitFirstPackager(testContainers);
            Container results =  testPacker.pack(products);
            if(results==null)
                return false;
            else 
                return true;
        }
        catch(Exception e)
        {
            return false;
        }
    }

    private void pack(ArrayList<BoxItem> products, int hashId ,int boxsize)
    { 
        ArrayList<Container> testContainers = new ArrayList<Container>();
        testContainers.add(GetContainer(boxsize));
        Packager packer = new LargestAreaFitFirstPackager(testContainers);
        Container results =  packer.pack(products);
        packedContainerMap.put(hashId, results);
        return; //results;
    }
    private Container pack(ArrayList<BoxItem> products , int boxsize)
    { 
        ArrayList<Container> testContainers = new ArrayList<Container>();
        testContainers.add(GetContainer(boxsize));
        Packager packer = new LargestAreaFitFirstPackager(testContainers);
        Container results =  packer.pack(products);
        return results;
    }

    private void PrepareProductsToPack(List<Product> products) 
    {
        productsToPack = new ArrayList<BoxItem>();
        for(Product product : products)
        {
            for(int i = 1; i < product.getQuantity(); i++)
            {
                productsToPack.add(new BoxItem(new Box(product.getSku(),
                                                        product.getProductDimensions().getRoundedWidth(),
                                                        product.getProductDimensions().getRoundedDepth(),
                                                        product.getProductDimensions().getRoundedHeight(),
                                                        product.getProductDimensions().getRoundedWeight())));
            }
        }
    }
    private Container GetContainer(int boxsize)
    {
        switch(boxsize)
        {
            case 1: return new Container("1", 10, 16, 6, 1000);
            case 2: return new Container("2", 11, 17, 11, 1000);
            case 3: return new Container("3", 12, 18, 15, 1000);
            case 4: return new Container("4", 13, 21, 16, 1000);
            case 5: return new Container("5", 17, 28, 17, 1000);
            default: return null;
        }
        //return null;
    }

    private static ArrayList<ArrayList<BoxItem>> splitProductSet (ArrayList<BoxItem> list, final int L) {
        ArrayList<ArrayList<BoxItem>> results = new ArrayList<ArrayList<BoxItem>>();
        for (int i = 0; i < L; i++) {
            ArrayList<BoxItem> items = new ArrayList<BoxItem>();
            items.addAll(list.subList(i * list.size() / L, (i + 1) * list.size() / L));
            results.add(items);
            System.out.println(items);
        }
        return results;
    }

I guess my biggest concern is that since I learned java in literally 1 month ('learned' I know C# as you can tell from the brackets being on new lines I'm sure) I'm not sure if I am following any best practices. For example my hashmapId feels insecure in the sense that the Id in the productSetsMap is not the same Object but instead the value is the same in packContainerMap.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.