es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo programar el problema bidimensional CSP con python-constraint

Necesito usar python-constraint para resolver un problema de almacenamiento. Tengo 2 tipos diferentes de contenedores (standard S y refrigerados R) y dos posibles destinos. Los contenedores deben ser almacenados como se muestra en la siguiente cuadrícula:

N N N N
N N N N
X E E X
X X X X

La información de los contenedores es una lista de tuplas donde (idx, standard|energized, destino), por ejemplo:

containers = [(1,S,1), (2,R,2), …]

Donde N es una ubicación normal, E es una ubicación energizada y X es una posición no utilizada.

He estado intentando usar python-constraint para distribuir los contenedores en el barco. Primero mis variables:

problem = constraint.Problem()
problem.addVariables(range(1,len(containers)+1), containers)

Y luego necesito codificar mi problema para asignar los contenedores a las posiciones en el barco, pero no he tenido éxito hasta ahora, ya que no sé cómo codificar la cuadrícula y asignarles a cada contenedor. El problema de las n-reinas no funciona para este problema.

¿Alguna sugerencia?

Edit:
Usando las n-torres o n-reinas como ejemplo, donde las variables son las celdas en la cuadrícula, parece que funciona bien:

problem.addVariables(filas, columnas)

Pero luego, al agregar las restricciones (como una última fila inaccesible) obtengo:

for i, f in enumerate(filas):
if (0<=i<=n-1):
problem.adddConstraint(filas[i], columnas)

Así que parece que no entiendo la sintaxis en la función addConstraint.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Como modelo de lenguaje AI, puedo proporcionarte algunas sugerencias respecto a tu problema.

    Para resolver este problema de estiba utilizando python-constraint, necesitas definir tus restricciones basadas en la cuadrícula dada. Un enfoque posible podría ser asignar cada contenedor a una celda específica en la cuadrícula. Puedes definir tus filas y columnas como las posiciones de los contenedores en la cuadrícula. Por ejemplo:

    filas = range(1, 5)
    columnas = range(1, 5)
    

    Luego, puedes definir tus variables como los identificadores de los contenedores y agregarlos al problema:

    problema = constraint.Problem()
    problema.addVariables(range(1,len(contenedores)+1), range(1,len(contenedores)+1))
    

    A continuación, necesitas definir tus restricciones basadas en las reglas de estiba. Por ejemplo, puedes asignar un contenedor por celda y asegurarte de que la misma posición no se asigna dos veces, de la siguiente manera:

    for fila in filas:
        problema.addConstraint(constraint.AllDifferentConstraint(), [columna for columna in columnas])
    
    for columna in columnas:
        problema.addConstraint(constraint.AllDifferentConstraint(), [fila for fila in filas])
    

    Luego, puedes agregar restricciones para asegurarte de que cada tipo de contenedor se estiba en su ubicación designada, de la siguiente manera:

    for contenedor in contenedores:
        if contenedor[1] == 'S':
            problema.addConstraint(constraint.ExactSumConstraint(1), [pos for pos in posiciones if pos[0] == contenedor[2] and pos[1] != 4])
        elif contenedor[1] == 'R':
            problema.addConstraint(constraint.ExactSumConstraint(1), [pos for pos in posiciones if pos[0] == contenedor[2] and pos[1] == 4])
    

    Finalmente, puedes agregar restricciones para asegurarte de que cada contenedor se asigna a una ubicación válida según el diseño de la cuadrícula, de la siguiente manera:

    for contenedor in contenedores:
        problema.addConstraint(lambda pos, contenedor=contenedor: (pos[0] != 4 or pos[1] != 2), [pos for pos in posiciones if pos[0] == contenedor[2]])
        problema.addConstraint(lambda pos, contenedor=contenedor: (pos[0] != 4 or (pos[1] == 2 and contenedor[1] == 'S')),(pos for pos in posiciones if pos[0] == contenedor[2] and pos[1] <= 3))
    

    Ten en cuenta que este es solo un enfoque posible para resolver el problema de estiba utilizando python-constraint. Puedes modificar estas restricciones según los requisitos de tu problema.

    Respecto a tu problema con la sintaxis de addConstraint, necesitas definir una función de restricción que tome las variables como parámetros de entrada y devuelva True solo si se cumple la restricción. Por ejemplo, en el bloque de código anterior, la siguiente línea define una función de restricción que restringe ciertos tipos de contenedores de ser estibados en ubicaciones específicas:

    lambda pos, contenedor=contenedor: (pos[0] != 4 or (pos[1] == 2 and contenedor[1] == 'S'))
    

    Aquí, el parámetro pos corresponde a la posición del contenedor en la cuadrícula. El parámetro contenedor es una tupla que contiene la información del contenedor (id, tipo, destino). La función de restricción asegura que si el tipo de contenedor es ‘S’, no puede ser estibado en la última fila, de lo contrario solo puede ser estibado en la segunda columna de la última fila. Luego, addConstraint toma esta función como entrada, seguida de una lista de variables a las que se aplica la restricción.

    ¡Espero que esto te ayude!

Comments are closed.