¿Sistema de inventario autoorganizado / inteligente?

11

La semana pasada estuve trabajando en un sistema de inventario con Unity3D. Al principio recibí ayuda de los chicos de Design3, pero no pasó mucho tiempo hasta que nos separamos, porque realmente no me gustó la forma en que hicieron su código, no olía a OOP en absoluto.

Avancé un paso más adelante: los artículos ocupan más de una ranura, el sistema de colocación avanzada (los artículos hacen todo lo posible para encontrar el mejor ajuste), el sistema de mouse local (el mouse queda atrapado en el área activa de la bolsa), etc.

Aquí hay una demostración de mi trabajo.

Lo que nos gustaría tener en nuestro juego es una función de organización automática, no una clasificación automática. Queremos esta función porque nuestro inventario estará en 'tiempo real', no como en Resident Evil 1,2,3, etc., donde pausarías el juego y harías cosas en tu inventario. Ahora imagínate a ti mismo en una situación difícil rodeada de zombis, y no tienes balas, miras a tu alrededor, ves que hay balas cerca en el suelo, así que ve por ellas e intenta recogerlas, pero no no encaja! Usted mira su inventario y descubre que si reorganiza algunos de los artículos, ¡encajará! - ahora el jugador - en esa situación no tiene tiempo para reorganizarse porque está rodeado de zombis y morirá si se detiene y organiza el inventario para hacer espacio (recuerde el inventario en tiempo real, sin pausa) - no ¿Sería bueno que eso sucediera automáticamente? - ¡Si!

(Creo que esto se ha implementado en algunos juegos como Dungeon siege o algo así, así que seguro que es factible)

Eche un vistazo a esta imagen, por ejemplo:

¿Qué hace la clasificación automática?

Sí, así que si ordena automáticamente el problema, obtendrá sus espacios, pero es malo porque: 1- Caro: no necesita una operación de clasificación completa para liberar esos espacios, en la primera imagen, simplemente deslice el elemento rojo en el abajo a la izquierda, y obtienes los mismos espacios que obtuviste de la clasificación automática. 2- Es molesto para el jugador: "¿Quién demonios te dijo que volvieras a ordenar mis cosas?"

No estoy preguntando "Cómo escribir el código" para esto, solo estoy pidiendo orientación, dónde buscar, ¿qué algoritmos están involucrados? ¿Es esto algo relacionado con gráficos y cosas de la ruta más corta? Espero que no, porque no pude continuar mis estudios universitarios: / Pero si es así, solo dímelo y aprenderé todo lo relacionado.

Tenga en cuenta que podría haber más de una solución. Así que supongo que lo primero que tengo que hacer es averiguar si la situación es 'solucionable'; si sé cómo determinar si una situación es solucionable o no, entonces puedo 'resolverla'. Solo necesito saber las condiciones que lo hacen 'solucionable'. Y creo que debe haber algún algoritmo / estructura de datos para esto.

Aquí hay una foto para más de una solución de tratar de ajustar un elemento 1x3:

ingrese la descripción de la imagen aquí

Las flechas muestran solo una de las soluciones, pero si mira, encontrará más de una. Esto es lo que finalmente no clasifico automáticamente, sino que encuentro una solución y la aplico.

Tenga en cuenta que si paso el tiempo, encontraré una manera de resolverlo, pero no sería la mejor manera, ¡es como sostener una rueda de automóvil con los pies en lugar de las manos! XD O simplemente como tratar de resolver un problema que requiere matrices, ¡pero aún no eres consciente de su existencia! Entonces, ¿cuál es el enfoque correcto para esto?

Actualizaciones de comentarios

@Stephen Realmente no soy un gurú en Alogs, mencionaste 'mochila' y @BlueRaja - Danny Pflughoeft mencionó algo de embalaje de contenedores 2D. ¿Están de alguna manera relacionados / iguales? - Todavía estoy confundido sobre cómo debería abordar esto.

Y sí, ya estoy usando una "heurística", pero realmente no sabía que estaba: D encuentra la primera ranura disponible, y ver si el elemento encaja allí.

No sé si ordenar artículos en función de su "volumen" (que llamo nSlotsRequired = nRowsReq * nColsRec) funcionaría, porque tiene un 2x2 y 1x4, por ejemplo, tienen el mismo volumen, pero diferentes formas y tendrán un efecto diferente sobre cómo irá el resto de los elementos a continuación. ENTONCES... :/

Vi este video, me gustó mucho la idea de empaque completo, pero me pregunto cómo hacerlo, ya que el inventario es 2D. Ni siquiera estoy seguro de que el embalaje del contenedor sea la clave aquí porque, bueno, es cierto que puedo tener más de una bolsa, pero en nuestro juego solo será una bolsa. Por lo tanto, se trata de colocar artículos en una 'bolsa' y no más que eso. Entonces, los ejemplos en ese video (las tuberías y los autobuses) realmente no coinciden con mi problema. También vi algunas cosas sobre esta mochila, no vi cómo el 'valor' está relacionado con mis artículos / inventario, pero supongo que 'peso' es lo mismo que el volumen, no estoy seguro.

vexe
fuente
77
Este es el embalaje 2D, que es NP-Complete. Por lo tanto, cualquier algoritmo que le dirá si puede ajustar todos los elementos será ineficiente (en el peor de los casos). Sin embargo, puede encontrar algunos algoritmos de aproximación bastante buenos.
BlueRaja - Danny Pflughoeft
Esta es exactamente la razón por la que decidí el (más común en estos días) modelo de inventario de un espacio por elemento en lugar de este. Desearía tener una solución para ti, renuncié a este problema ...
Ryno
@ BlueRaja-DannyPflughoeft Me pregunto si un algoritmo simple / eficiente está disponible si los elementos se limitan a ciertas formas.
congusbongus
Limitar las formas no reduce la complejidad, sino que hace que sea más fácil pensar en ello, por lo que cree que se ha manejado la complejidad, afaik.
Patrick Hughes
@VeXe Lo siento, me perdí la actualización de tu pregunta. El embalaje y la mochila no son lo mismo. Pero ambos son problemas de embalaje. El 'valor' en su caso es la forma y el tamaño de sus objetos de inventario.
Stephen

Respuestas:

8

Esta es una variación del problema de la mochila. Como Danny Pflughoeft menciona es NP-Complete. Lo que significa que no se puede resolver en tiempo lineal, si no recuerdo mal.

Pero puedes intentar resolver esto en varios pasos. Básicamente es un problema de clasificación.

Comenzaría calculando el 'volumen' de cada elemento: esto podría calcularse de varias maneras:

  • volumen = max (largo, ancho);

  • Volumen = largo * ancho

  • Volumen = sqrt (largo * ancho)

Luego comience a poner los artículos con la puntuación más alta primero en el inventario. Dado que lo más probable es que no encajen en el espacio restante más tarde. Los artículos pequeños encajarán siempre.

Necesita una heurística (un nombre elegante para adivinar con conocimiento de causa ;-)) para su estrategia de colocación. Algo así como tratar de encajar elementos en la primera ranura libre desde la parte superior izquierda o algo así.

La estrategia de clasificación de inventario de Diablo II funcionó de manera similar, creo. Cosas como espadas y lanzas terminarían arriba a la izquierda, luego ropa y armadura, luego escudo y así sucesivamente.

Creo que realmente necesita probar esto y ajustar el algoritmo (cálculo de volumen diferente, heurística diferente), hasta que funcione lo suficientemente razonable.

Stephen
fuente
1
NP-complete es un conjunto de problemas con una complejidad mayor que el polinomio. Para un inventario relativamente pequeño (menos de mil artículos, diría :)), incluso el algoritmo exponencial funcionaría bastante rápido, porque un paso de dicho algoritmo lleva muy poco tiempo. Sin embargo, usar su idea debería ser lo suficientemente bueno y más fácil que implementar un algoritmo de programación dinámico -> +1
MartinTeeVarga
Gracias por el voto a favor. Sí, el inventario no debería ser potencialmente infinito, por lo que los algoritmos exponenciales deberían funcionar bien ^^
Stephen
@ sm4: Un millar es típicamente un número enorme para problemas de NP-Complete. Recuerde, estos problemas son O (2 ^ n) - ¡incluso solo 2 ^ 64 es computacionalmente inviable!
BlueRaja - Danny Pflughoeft
3

Jaja, @ Todos los que ayudaron, gracias. Finalmente pude resolverlo. Esto es lo que básicamente hice:

IEnumerator AddItem_Sorted (Item item)
  1. Condición trivial: verifique si obtuvimos los nRequiredSlots mínimos para que el artículo se ajuste, si lo tenemos, proceda ...
  2. vamos a vaciar toda la bolsa, colocando los artículos en un marcador de posición (lista o algo)
  3. agregue el elemento deseado a la MUY última ranura / lugar en el que podría caber, asegurándose de que esté seguro en su forma horizontal
  4. usando el primer algoritmo decreciente agregaremos el resto de nuestros artículos
  5. durante la adición, usaremos programación dinámica (memorización) para recordar ese índice que estamos agregando en (índice de la próxima ranura disponible)
  6. Si todo lo que se agrega es exitoso, hemos logrado ajustar nuestro artículo deseado, y de alguna manera clasificamos la bolsa, de artículos grandes a pequeños
  7. Si no pudiéramos agregar todos los elementos, esto significa que no era una situación solucionable, por lo que tenemos que llevar la bolsa a su estado anterior
  8. Una forma de hacerlo, (salió de la superficie de mi mente), es copiar el estado de la bolsa antes de toda esta operación, y luego si falla, pasaremos a ese estado anterior, o incluso mejor, durante el ' vaciando la bolsa, memorizamos dónde estaba cada elemento, de modo que si la operación falla, los recuperaremos, usando AddItem (elemento, índice), en sus índices anteriores :)
  9. todo este proceso puede llevar tiempo, por lo que podríamos dividir la carga en fotogramas separados, utilizando mi hermoso rendimiento :)
  10. HECHO ! \ m / (@ ~ 9: 00)

ACTUALIZAR:

  1. Hice una matriz que almacenaba los índices de todos los elementos agregados, de esa manera no tengo que ir a buscar las ranuras ocupadas para liberarlas, gran impulso.

  2. no es necesario agregar en el último espacio, de hecho, a veces puede que no funcione de esa manera, agregué el elemento deseado al resto de los otros elementos y lo ordené con ellos.

Como puede ver en el video, necesita un poco de optimización, la clasificación no es perfecta, me gustaría usar el empaquetado completo, pero ya es codicioso para el rendimiento. Estoy abierto a cualquier sugerencia de optimización, gracias de nuevo :)

vexe
fuente
¡De nada! :) Me gustaría agradecer a BlueRaja - Danny Pflughoeft por mencionar el embalaje del contenedor, @Stephen por la idea de volumen y Richard Buckland por su conferencia de programación dinámica, y todas las conferencias.
vexe