Recebi uma tarefa para criar uma estimativa de remessa que sugira a melhor acomodação de mercadorias com o menor número possível de caixas:
Existe um conjunto finito de tamanhos de caixas retangulares conhecidos
Há muitos itens retangulares arbitrários para serem embalados dentro de caixas
O menor número de caixas deve ser usado da melhor maneira. Como enviar duas caixas 1x1x1 é muito mais caro que uma caixa 1x2x1. Essa deve ser a prioridade aqui.
Também deve ser otimizado para usar as caixas menores quanto possível, como uma prioridade de segundo nível. (por exemplo: se for apresentada uma escolha entre uma caixa maior e duas pequenas, deverá escolher a caixa maior)
Os itens podem ser girados para caber na caixa, mas a rotação deve ser limitada a incrementos de 45 ° no mínimo (em minhas pesquisas, parece que algumas configurações permitem uma rotação de 45 graus para melhor encaixar as caixas retangulares dentro de uma caixa retangular maior) , sendo rotações de 90 ° o padrão a ser adotado.
As caixas têm um limite de peso e os itens têm pesos arbitrários (por exemplo: um item com tamanho de 1x1x1 pode ser mais conveniente do que outro item de 2x2x2)
Pesquisei um pouco e encontrei alguns algoritmos abstratos sobre empacotamento de lixeira e o problema da mochila e vim com a seguinte variação de força bruta, semelhante ao algoritmo de melhor ajuste:
Classifique os itens em ordem decrescente de volume (maior primeiro) na lista "itens a serem embalados"
Para cada item desta lista:
Escolha a caixa menor que está na lista "caixas usadas" e tem limite de volume e peso restante suficiente para caber no item (usarei fit aqui para significar o ajuste das dimensões e peso)
Se não houver essa caixa, crie uma nova caixa a partir do conjunto conhecido de possíveis tamanhos de caixa, que seja o menor tamanho que possa caber nas dimensões e peso do item e adicione-o à lista de "caixas usadas".
Se uma caixa couber no item (usando a função de encaixe abaixo), adicione-a à lista de "itens desta caixa" e remova-a da lista "itens a caber", marcando sua posição 3d relativa dentro da caixa.
Repita do item 2.1 até que não exista nenhum item na lista "itens a serem embalados".
A função de verificação de encaixe usada na etapa 2 acima:
Verifique se o volume restante da caixa corresponde ao volume do item. Caso contrário, retorne false.
Verifique se a soma do peso dos "itens da caixa" mais o peso do item atual é menor ou igual ao limite de peso da caixa. Caso contrário, retorne false.
Marque a lista "itens da caixa" para escolher a primeira coordenada da caixa que tenha o menor componente Y e que tenha espaço suficiente para a largura, profundidade e altura do item, considerando os outros itens colocados como espaço indisponível.
Se o item não se encaixar na orientação atual, gire-o em uma das 6 rotações possíveis, não assumindo rotações de 45 ° por simplicidade. (As rotações que resultam em tamanhos que já testados podem ser pulados. Por exemplo: girar uma caixa 180 ° fornece as mesmas dimensões da posição original, porque todas as caixas e itens têm o mesmo tamanho para faces opostas e, portanto, podem ser pulados.)
Se o item não tiver sido rotacionado de todas as formas possíveis, de volta à sua orientação original, tente novamente a partir da etapa 3.
Se todas as rotações foram tentadas e nenhum ajuste foi encontrado, considere a coordenada atual como espaço indisponível.
Se não houver espaço disponível para verificação, retorne false. Caso contrário, tente novamente a partir da etapa 3.
Quero saber se pode haver uma melhor solução para o meu problema, dadas as restrições apresentadas.
Isso parece funcionar na teoria, mas eu não tentei no código. Desejo saber se estou indo na direção certa ou se há maneiras melhores e com melhor desempenho.
Referências seria ótimo.
Editar:
Encontrei algumas APIs de terceiros interessantes que fazem o que eu quero, mas isso precisa ser desconectado, por isso não terei acesso a elas.
Alguns exemplos são:
Edição 2:
Um exemplo do mundo real de problema a ser resolvido seria:
- Tenho 4 tamanhos de caixa LxAxP: 10x12x18, 12x16x24, 16x20x30, 24x32x40
- Tenho um pedido de 4 itens, sendo 1 do tamanho 6x8x10, 2x 22x14x30 e 1x 22x4x20
Como encaixo esses itens em qualquer quantidade de caixas de um ou mais tamanhos usando o menor número possível de caixas, usando as menores caixas possíveis e deixando menos espaço livre possível?
packing
tag relacionada;algorithms
sufixos :)