Recibí la tarea de crear una estimación de envío que sugiera el mejor alojamiento de productos en la menor cantidad de cajas posible:
Existe un conjunto finito de tamaños de cajas retangulares conocidas.
Hay muchos elementos arbitrarios retangulares para ser embalados dentro de cajas
Cuantas menos cajas se deben usar, mejor. Porque enviar dos cajas 1x1x1 es mucho más costoso que una caja 1x2x1. Esta debería ser la prioridad aquí.
También debe optimizarse para usar los cuadros más pequeños como sea posible, como prioridad de segundo nivel. (por ejemplo: si se le presenta la opción entre una caja más grande y dos más pequeñas, debería elegir la caja más grande)
Los artículos se pueden rotar para ajustarse a la caja, pero la rotación debe limitarse a incrementos de 45 ° como mínimo (en mis investigaciones parece que algunas configuraciones permiten una rotación de 45 grados para adaptarse mejor a las cajas retangulares dentro de una caja retangular más grande) , siendo las rotaciones de 90 ° el estándar a tomar.
Las cajas tienen un límite de peso y los artículos tienen pesos arbitrarios (por ejemplo: un artículo cuyo tamaño es 1x1x1 puede ser más pesado que otro artículo 2x2x2)
Investigué un poco y encontré algunos algoritmos abstractos sobre el embalaje de la papelera y el problema de la mochila y encontré la siguiente variación de fuerza bruta, similar al algoritmo de mejor ajuste:
Ordenar los artículos en orden de volumen decreciente (primero los más grandes) en una lista de "artículos para empacar"
Para cada artículo en esta lista:
Elija el cuadro más pequeño que está en la lista de "cuadros usados" y tiene suficiente volumen restante y límite de peso para el artículo (usaré el ajuste aquí para indicar el ajuste de las dimensiones y el peso)
Si no existe dicho cuadro, cree un cuadro nuevo a partir del conjunto conocido de tamaños de cuadro posibles que sea el tamaño más pequeño que pueda ajustarse a las dimensiones y el peso del artículo y agréguelo a la lista de "cuadros usados".
Si un cuadro se ajusta al elemento (usando la función de ajuste a continuación), agréguelo a la lista de "elementos de este cuadro" y retírelo de la lista de "elementos para ajustar", marcando su posición 3d relativa dentro del cuadro.
Repita desde 2.1 hasta que no haya ningún elemento que se pueda ajustar en la lista de "elementos para empacar".
La función de verificación de ajuste utilizada en el paso 2 anterior:
Compruebe si el volumen restante de la caja se ajusta al volumen del artículo. Si no, devuelve falso.
Compruebe si la suma del peso de los "artículos de la caja" más el peso del artículo actual es menor o igual al límite de peso de la caja. Si no, devuelve falso.
Verifique la lista de "elementos del cuadro" para elegir la primera coordenada del cuadro que tenga el componente Y más pequeño y que tenga suficiente espacio para el ancho, la profundidad y la altura del elemento, considerando los otros elementos colocados como espacio no disponible.
Si el artículo no se ajusta a su orientación actual, gírelo en una de las 6 rotaciones posibles, sin suponer que la rotación sea de 45 ° por simplicidad. (Las rotaciones que dan como resultado tamaños que ya se probaron se pueden omitir. Por ejemplo: al girar una caja 180 ° se obtienen las mismas dimensiones que la posición original porque todas las cajas y elementos tienen el mismo tamaño para las caras opuestas, por lo que se pueden omitir)
Si el elemento no se ha girado en todas las formas posibles de regreso a su orientación original, intente nuevamente desde el paso 3.
Si se probaron todas las rotaciones y no se encontró ajuste, considere la coordenada actual como espacio no disponible.
Si no hay espacio disponible para verificar, devuelva falso. De lo contrario, intente nuevamente desde el paso 3.
Quiero saber si puede haber una mejor solución a mi problema, dadas las limitaciones presentadas.
Esto parece funcionar en teoría, pero no lo he probado en código. Deseo saber si voy en la dirección correcta o si hay formas mejores y eficaces de hacerlo.
Las referencias serían geniales.
Editar:
He encontrado algunas API de terceros interesantes que hacen lo que quiero, pero esto tendrá que desconectarse, por lo que no tendré acceso a ellas.
Algunos ejemplos son:
Edición 2:
Un ejemplo real del problema a resolver sería:
- Tengo 4 tamaños de caja WxHxD: 10x12x18, 12x16x24, 16x20x30, 24x32x40
- Tengo un pedido de 4 artículos, siendo 1 de tamaño 6x8x10, 2x 22x14x30 y 1x 22x4x20
¿Cómo encajo estos artículos en cualquier cantidad de cajas de uno o más tamaños usando la menor cantidad de cajas posible, usando las cajas más pequeñas posibles y dejando menos espacio libre posible?
fuente
packing
etiqueta relacionada;algorithms
Respuestas:
El embalaje del contenedor es muy difícil computacionalmente. Piense en la mitad del problema: desea empacar el producto en cajas de envío sin desperdicio en la caja. Una solución óptima para eso requeriría pasar por todos los subconjuntos posibles y todas las posibles disposiciones en 3D del producto que debe enviarse en un camión. Te daré la solución óptima para eso porque tengo un amigo que hace seis cosas imposibles antes del desayuno.
Ahora solo tiene que poner todas las cajas en el camión sin desperdicio. Mi amigo hace su segunda cosa imposible y te da la solución. Desafortunadamente, con los tamaños de cajas que seleccionó anteriormente, hay un espacio vacío en el camión que podría reducirse si hubiera elegido cajas diferentes (ya sea más grandes o más pequeñas) en la primera tarea. Si cambia el tamaño de una caja, en el mejor de los casos tendrá que volver a empacar el camión; en el peor de los casos, es posible que deba volver a embalar todas las cajas, lo cual es tan difícil como el problema con el que comenzamos. Y, como con la primera etapa, tendrías que probar todos los arreglos 3D posibles.
Encontré que el Manual de diseño de algoritmos de Skiena es útil para pensar qué clase de algoritmos se adapta a qué tipo de problemas, pero principalmente aprendí que las buenas soluciones para problemas incluso mundanos explotan en tu cara con dificultades computacionales. La mayor parte de lo que necesita encaja en la clase de problemas de embalaje y ese artículo es un buen punto de partida. Vale la pena señalar que algunos de los mejores algoritmos para esto son los productos comerciales porque esta tarea aparece en todas partes en logística (¿cuál es el menor número de vagones de tren en los que puedo meter mis productos? Y tal). Se puede ganar mucho dinero si la heurística correcta puede ahorrarle al fabricante 100 vagones de tren al mes.
Desafortunadamente, la literatura sobre la optimización de la heurística no es tan grande como la de los algoritmos. Si intentas hacerlo solo, te garantizo que estarás soñando con mover prismas rectangulares en tu segundo mes. Tuve un problema de corte de material que si tuviera que hacerlo de nuevo, probablemente trabajaría con los expertos (o su software de propiedad).
Gracias a @JTrana por la excelente expansión de mi comentario.
fuente
Al crear nuevos algoritmos, y recientemente acabo de hacer un algoritmo de empaque por mí mismo (sé que todavía tiene algún potencial de optimización), siempre hago el enfoque más simple:
¿Cómo lo haría yo como humano y trataría de traducirlo a un algoritmo? De mi maestro de IA (robótica) Rolf Pfeifer, todavía tengo en cuenta que esa inteligencia aparente a veces se puede crear con algunas reglas muy simples, así que en lugar de la ingeniería excesiva Trato de sub-ingeniero
Para los elementos restantes, busque el nuevo mejor cuadro. ...
X. siempre piense en eventos excepcionales (artículos de gran tamaño, formas extrañas, si una caja contiene solo 1 artículo, ¿no sería mejor enviar un artículo sin caja ?, etc.) pero también puede tomar una heurística en forma de decisión árbol.
Por supuesto, hay más advertencias a medida que avanzas, solo doy estas ideas como punto de partida. A partir de ahí hay muchas formas posibles. Una alternativa sería dividir una caja en pequeños cubos (por ejemplo, 5cmx5cmx5cm) y rastrearlos como ocupados / libres, otro enfoque podría llamarse tetris 3d, etc.
Con este enfoque, no tiene que preocuparse necesariamente por la explosión combinatoria. Por otro lado, podría ocurrir una explosión combinatoria si estamos hablando de cargas de trenes de artículos, pero de nuevo: ¿Realmente cree que una compañía verificará la lista de empaque artículo por artículo? No, se acercarán a una solución de divide y vencerás: divide la complejidad mediante el uso de volúmenes estandarizados (por ejemplo, paletas o cajas de tamaño fijo). Entonces, incluso por razones prácticas, tenga en cuenta que no solo entrena, a veces el tiempo de los empleados también es dinero. un tren puede cargar x paletas, cada paleta tiene un volumen fijo, así que empaca los artículos en la paleta, pero de nuevo, tal vez una paleta consta de varios pedidos, así que usa cajas fijas para los artículos, que luego se cargan en paletas, que luego se cargan en trenes
Al menos así es como yo, como humano, trataría la tarea, obtendría la mejor caja y luego encajaría el elemento más grande uno por uno en el espacio más pequeño disponible (y agregaría un poco de vista previa).
Como en mi algoritmo, al final probablemente no tenga la mejor solución, sino una heurística muy buena que luego puede refinar aún más.
A veces es más fácil comenzar con el primer paso y resolver los problemas en el camino, por supuesto, idealmente no es una especie de paso al límite, sino un poco inteligente ... a veces puede verse obligado a explorar alternativas y elegir el mejor o implementar un "paso atrás".
Pero como aprendí de mi maestro de IA (Rolf Pfeifer, lamento molestarme con eso nuevamente): a veces puedes crear un comportamiento inteligente aparente con algunos conjuntos de reglas muy simples y pocos> comportamiento emergente en el ejemplo mencionado, programaron pequeños autos remotos para girar a la izquierda si detectan un obstáculo en el lado derecho, giran a la derecha si hay un obstáculo en el lado izquierdo y van derecho si no hay obstáculo o si el obstáculo está al frente. 3 o 4 robots como ese, colocados en un cuadrado de 3 mx 3 m con muchas pelotas de ping-pong conducen al sorprendente hecho de que los robots parecían estar limpiando, empujando las pelotas de ping-pong hacia las esquinas, a pesar de que los robots están solo programado para evitar obstáculos.
PD: La única desviación del mundo real que encontré con este enfoque es cuando estaba trabajando a tiempo parcial como escenógrafo para grandes conciertos como Metallica, Iron Maiden, Britney Spears, Paul McCartney, U nombrarlo ... Los camioneros que trabajan en el giras internacionales tienen listas de embalaje precisas artículo por artículo. Los cálculos se realizan una vez (no lo sé por humanos o máquinas), y luego se replican. A veces, cuando empacan por primera vez, incluso hacen fotos capa por capa y lo pegan dentro del camión para que los equipos locales sepan exactamente, qué caja debe cargarse cuándo y dónde. Pero esta también es una necesidad de embalaje específica, ya que para un recorrido siempre trabajan con las mismas cajas y camiones.
fuente
La heurística que mencionas en tu publicación parece interesante.
Sugeriría un par de modificaciones para mejorar la solución final.
Dada una solución con todos los artículos empaquetados en una caja, intente fusionar el contenido de dos cajas pequeñas en una caja más grande (esto debería ayudar a mejorar su criterio de usar la menor cantidad de cajas posible).
Alternativamente, cada vez que inicie un nuevo cuadro, en lugar de utilizar el cuadro más pequeño que pueda acomodar el elemento actual, puede elegir el cuadro más grande que pueda acomodarlo, y una vez que cada elemento se asigne a un cuadro, intente asignar todos los elementos de un caja a una caja más pequeña.
Además, en su función de ajuste, en lugar de considerar la posición de sus otras cajas como fija, puede imaginar cambiar la secuencia de carga. Esto debería permitirle encontrar mejores soluciones a expensas de un mayor tiempo de ejecución.
fuente