Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何创建一个算法,该算法将继续运行一个算法,直到在Java中成功_Java_Algorithm_Bin Packing - Fatal编程技术网

如何创建一个算法,该算法将继续运行一个算法,直到在Java中成功

如何创建一个算法,该算法将继续运行一个算法,直到在Java中成功,java,algorithm,bin-packing,Java,Algorithm,Bin Packing,我有一个包(),可以为我将项目打包到一个容器中。但是,如果有太多的项目,例如1000件衬衫,并且在我们拥有的最大容器中只有500件适合,它不会尝试包装剩余的500件。结果只返回null,并且不会尝试组合可用的容器 我正在处理一个箱子包装问题。请注意,这不需要是一个精确的解决方案,因为我们只是将运费的成本计算器放在一起。我偶然发现了一个处理大部分问题的软件包。基本上我有5个可用的容器。API收到产品的请求,我收集尺寸并打包。我最初的想法是检查包是否成功,然后将其添加到List packingRes

我有一个包(),可以为我将项目打包到一个容器中。但是,如果有太多的项目,例如1000件衬衫,并且在我们拥有的最大容器中只有500件适合,它不会尝试包装剩余的500件。结果只返回null,并且不会尝试组合可用的容器

我正在处理一个箱子包装问题。请注意,这不需要是一个精确的解决方案,因为我们只是将运费的成本计算器放在一起。我偶然发现了一个处理大部分问题的软件包。基本上我有5个可用的容器。API收到产品的请求,我收集尺寸并打包。我最初的想法是检查包是否成功,然后将其添加到List packingResults对象中,这样我就有了一个列表。但是这个软件包的设置方式,我怀疑如果不失去产品的完整性,它将无法工作

这是服务构造函数

public PackingService(List<Product> products) 
{
    containers = SetContainers();
    this.packer = new LargestAreaFitFirstPackager(containers);
    this.products = products;
    PrepareProductsToPack(products);
}
公共打包服务(列出产品)
{
containers=SetContainers();
this.packer=新的Largestreafitfirstpackager(容器);
这一点。产品=产品;
准备产品包装(产品);
}
实际包装方法

public List<Container> PackItems()
{
    packedResultContainers = new ArrayList<Container>();
    Container results =  packer.pack(productsToPack);
    return this.packedResultContainers;
}
public List PackItems()
{
packedResultContainers=new ArrayList();
容器结果=包装机包装(productsToPack);
返回此.packedResultContainers;
}
最后,这里是我的产品实体列表,并为打包算法做准备

    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())));
        }
    }
productsToPack=newarraylist();
用于(产品:产品)
{
对于(int i=1;i
我感到困惑的原因是,如果初始请求未能打包,那么我需要将列表拆分为2、3、4,具体取决于有多少项,而我无法知道需要有多少个列表

有人能提供一些关于我如何调整算法来处理这个问题的见解吗

我还应该说明,我这样做的原因是,一旦我有了结果列表,我会发出一个UPS Api请求,以收集运输方法及其费率

我正在为未来的用户更新我的答案,这就是我解决箱子包装问题的方法

public ArrayList<Container> PackItems()
{
    this.packingResults = new ArrayList<Container>();
    productSetsToPack = chopped(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 boxs
        ++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;
}
public ArrayList PackItems()
{
this.packingResults=新的ArrayList();
productSetsToPack=切碎(productsToPack,getInitBoxCount(productsToPack));
int hashMapId=0;
对于(int i=productSetsToPack.size()-1;i>=0;i--)
{
ArrayList itemsToPack=productSetsToPack.get(i);
productSetsMap.put(hashMapId,itemsToPack);
打包(itemsToPack,hashMapId,5);//打包最大尺寸的盒子
++hashMapId;
}; 
对于(Map.Entry:packedContainerMap.entrySet()){
int containerKey=entry.getKey();
容器packedContainer=entry.getValue();
int smallestBoxSize=getSmallestBox(productsetmap.get(containerKey),Integer.parseInt(packedContainer.getName());
packingfresults.add(pack(productSetsMap.get(containerKey),smallestBoxSize));
// ...
}
返回打包结果;
}

查看Spring重试是否有用。
在您怀疑无法获得第一个列表的方法中进行重试和不同的逻辑,依此类推。

您可以生成项目集合的所有可能子集,然后按排序顺序(从最大和减小的大小开始)迭代这些子集,直到成功

这当然不能很好地扩展。Id还使用列表索引而不是引用生成子集(将所有项目添加到列表中,创建一组从0到list.size()的数字,然后生成此集合的所有子集), 你想要的是很可能的。这将是一个相当大的任务,特别是如果你有5种不同的包装尺寸。我建议使用递归

创建一个方法,用于查找订单所能容纳的最大软件包的最小数量。假设它能装进4个大盒子。然后把每一个大盒子装进小盒子里。这些运行看起来类似于方框5是最大的方框,方框1是最小的方框

box5 - box5 - box5- box5
box5 - box5 - box5- box4
box5 - box5 - box5- box3
box5 - box5 - box5- box2
box5 - box5 - box5- box1
这段距离可以装进3个大盒子和1个小盒子

查找最大框的代码可能是类似这样的while循环

int boxCount = getInitBoxCount(products);

public int getInitBoxCount(ArrayList<BoxItems> items)
{
    if(productsFit(products,sizeLarge) == null)
    {
        ArrayList<BoxItems> temp1 = new ArrayList<BoxItems>();
        ArrayList<BoxItems> temp2 = new ArrayList<BoxItems>();

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

在当前版本中,此功能可以工作:

@Test
void testIssue158() {
    List<Container> containers = new ArrayList<>();
    containers.add(new Container("X",10, 10, 5, 1000));

    List<BoxItem> products = new ArrayList<>();
    for(int i = 0; i < 1000; i++) {
        products.add(new BoxItem(new Box(Integer.toString(i), 1, 1, 1, 1)));
    }

    LargestAreaFitFirstPackager packager = new LargestAreaFitFirstPackager(containers, false, true, true);
    List<Container> fits = packager.packList(products, 50, Long.MAX_VALUE);
    assertNotNull(fits);
    assertEquals(fits.size(), 2);
}
@测试
无效测试158(){
列表容器=新的ArrayList();
容器。添加(新容器(“X”、10、10、5、1000”);
列表产品=新的ArrayList();
对于(int i=0;i<1000;i++){
添加(新框项目(新框(Integer.toString(i),1,1,1,1));
}
LARGESTAREAFITFIRSTACKER packager=新的LARGESTAREAFITFIRSTACKER(容器,假、真、真);
列表拟合=分装商。包装列表(产品,50,长。最大值);
assertNotNull(fits);
assertEquals(fits.size(),2);
}

希望这意味着没有多容器配合的定制解决方案

这难道不是简单地一次又一次地重试相同的代码吗?如果打包“失败”(它不会抛出异常,而是只返回null),那么我需要说将我的产品列表拆分为第二个产品列表,然后打包两个产品,如果两个都失败,那么尝试3,这在理论上似乎永远不会结束,因此每次失败的尝试我都需要以某种方式动态创建一个新对象。这可能吗?你可以
Container[getInitBoxCount()] shipments //create an array of containers with the size of the inital box count 

for(Container c : shipments)
{
    c = new LargeContainer();
}


Container[] check; //create new objects into the check array. dont set one array = to anoter

do
{
    check = shipments //create new objects into the check array. dont set one array = to anoter
    for(Container c: shipments)
        getSmallestBox(5, c);
    combineBoxes(shipments);
}
while(check == shipments)
@Test
void testIssue158() {
    List<Container> containers = new ArrayList<>();
    containers.add(new Container("X",10, 10, 5, 1000));

    List<BoxItem> products = new ArrayList<>();
    for(int i = 0; i < 1000; i++) {
        products.add(new BoxItem(new Box(Integer.toString(i), 1, 1, 1, 1)));
    }

    LargestAreaFitFirstPackager packager = new LargestAreaFitFirstPackager(containers, false, true, true);
    List<Container> fits = packager.packList(products, 50, Long.MAX_VALUE);
    assertNotNull(fits);
    assertEquals(fits.size(), 2);
}