Trabajo problema de programación

votos
8

Estoy trabajando en una aplicación en la que necesito para programar automáticamente los trabajos para los miembros en un horario rotativo. No soy muy bueno para explicar las reglas, así que aquí tiene algunos datos para ayudar a cabo:

Posiciones: un puesto de trabajo, con normas tales como los lunes y los miércoles semanales.
Categorías: un conjunto de posiciones
Grupos: Otro conjunto de posiciones. Las posiciones en el mismo grupo no pueden ser asignados en el mismo día
Miembros: Los usuarios asignados a posiciones en una fecha determinada.

Para cada fecha en el mes, los miembros se asignan a posiciones (tanto en orden ascendente). Si un miembro se le asigna una posición en una categoría, la próxima vez que un puesto en la misma categoría aparece, el siguiente miembro alfabéticamente (o al principio de la lista) se asigna por ejemplo.

Miembros: M1, M2, M3, M4
Las posiciones en la Categoría C1: P1, P2, P3
miembros en la posición P1: M1, M2, M3, M4
miembros en la posición P2: M1, M2, M3
miembros en la posición P2: M1, M3, M4

Si M1 se asigna para P1, P2, si viene a continuación, se le asignará M2. Una capa adicional de complejidad se introduce en la que si P3 viene a continuación en cambio, se le asigna M3. El sistema tiene que seguir la pista del hecho de que M2 se 'salta' y asignar M2 siguiente si está disponible, a continuación, asignar M4 siguiente, o esperar hasta que llegue a una posición en la que M2 está disponible (esto se convierte, además, complejo cuando hay muchos 'saltado miembros).

Un miembro también se omite si se ha indicado que no estará disponible en esa fecha. El sistema tiene que dar prioridad a los miembros omitidos, de alguna manera identificarlos cuando suben y luego saltar a la siguiente persona en la lista de lógica. Saltarse también se aplica a los grupos debido a los choques de la fecha.

Ya tengo una solución [y desordenado] temporal que ya no entender a pesar de que tengo un montón de comentarios en el mismo explicando cada paso. Sus puntos débiles son en el trato con los miembros omitidos.

Si se va a codificar esta ¿cómo hacerlo? Estoy poniendo en práctica esto en PHP, pero pseudocódigo trabajaría también.

Publicado el 19/12/2009 a las 11:20
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
1

uff. No te entiendo descripción, pero en situaciones similares que he utilizado SQL para resolver este tipo de problema. si está utilizando php supongo que tienes SQL disponibles.

lo que sugeriría hacer es encontrar una manera de almacenar esta información en un conjunto de tablas y luego la elaboración de lo consulta SQL le da la respuesta que desea. muy a menudo es mucho más fácil de hacer en SQL que en un lenguaje de procedimientos.

para la parte omitida, por ejemplo, es posible que tenga una columna que registra cuando alguien se le asigna el pasado, y luego el fin de que (por lo que se selecciona la persona que no ha sido asignado por mucho tiempo). Alternativamente, usted podría tener el número de veces omiten como una columna y el orden por eso.

Respondida el 19/12/2009 a las 13:09
fuente por usuario

votos
6

Mi solución: Se necesita un PriorityQueue (que está disponible en PHP bajo SplPriorityQueue). El PriorityQueue le da elementos con prioridad descendente (ordenadas según los valores, el valor más pequeño tiene la prioridad más alta).

Cada miembro tiene un valor asignado. Este valor es un número ASCII con n dígitos (se puede usar 8 dígitos para mayor comodidad), se llenaron de ceros a n posiciones. Después de que añadir el nombre. También agrega a cada miembro de las posiciones disponibles

Así (n = 5):

  • valor M1: 99999Albert P1, P2, P3
  • Valor M2: 99999Susi P1, P2
  • Valor M3: 99999Bob P1, P3

Esto hace que sea fácil para ordenar los miembros de la prioridad y el nombre.

Preparación:

Un dia soleado. Va a recuperar las posiciones asignadas y una categoría para un día determinado. Cada miembro se cargó en una larga lista. Cada miembro que no aparece en el trabajo no está cargado, pero consigue su valor se redujo en dos menos. Bob no está aquí, por lo que su nuevo valor se 99997Bob. Esto significa que Bob se seleccionará automáticamente la próxima vez. Todos los demás miembros obtienen su valor disminuye por uno menos.

Las posiciones asignadas para un día específico se asignan (uso SplObjectStorage):

P1-> M1, M2, M3, M4, etc. P2-> etc.

El mapa contiene sólo las posiciones que deben ser asignados el día de hoy. Después de la

Filtro: Usted debe mirar hacia arriba los grupos y eliminar cualquier posición en el mapa que no se puede asignar este día. Su descripción del grupo es un poco confuso.

Asignar:

  • Solo tiene que elegir la posición para asignar
  • Obtener la lista de miembros que puede ocupar el puesto
  • Eliminar miembros disponibles de la lista y ponerlos en el PriorityQueue
  • Asignar la posición por el extracto () desde PriorityQueue (asignación correcta se realiza automaticially). Cada miembro que se asigna voluntad toma su valor incrementado en uno (lo que la disminución y aumento de los niveles de si usted está aquí y trabajar). Si no está aquí y no asignados a una posición por cualquier razón, se obtiene una pequeña penalización de uno. Si no aquí, se obtiene una penalización de dos.
  • Después de la terminación, ponga los miembros restantes de la lista de nuevo, desactive la PQueue y continuar con la siguiente tarea.

advertencias:

  • Usted debe tener cuidado de que siempre hay suficiente gente para una posición.
Respondida el 02/01/2010 a las 16:10
fuente por usuario

votos
0

Lo que entiendo es que hay miembros de la 'm' y 'n' posiciones.

Categoría: un grupo de posiciones - un miembro que se le asigna una posición en la categoría no puede tener otro?

Grupo: un grupo de posiciones - las posiciones en el mismo grupo se le debe asignar en días diferentes.

Lo último, una posición que tiene una lista de miembros que puede llenarlo.

En cuanto a esto desde un punto de vista de la estructura de datos, puso a los miembros de una lista enlazada - cada miembro tiene que tener una lista adicional de [posición, día] que son finalmente asignados. Luego, para cada posición, tener una lista de referencias a los miembros que pueden llenar esa posición. Implementar categorías como otra lista de referencias para una posición en cuanto a que las categorías que se encuentra.

La asignación real: tiene un contador de día = 0, e iterar a través de las posiciones. Para cada posición P, iterar a través de los miembros que puede llenarlo. Un miembro de M puede llenar la posición si:

  • Cualquier cargo que ha llenado P2 no comparte una categoría con P.
  • Cualquier posición que él ha llenado con P2 = día daycounter no comparte un grupo con P.

Si es capaz de ocupar el puesto, la [posición, día] se añade par al miembro, y el nodo del miembro es trasladado al final de la lista (esta es la razón por referencias son necesarias - todas las referencias siguen siendo válidos a pesar de que la nodo desplazado). Esto asegura que el 'saltarse' miembros se les da la más alta prioridad, y los miembros que no se alcanzaron fueron dadas siguiente prioridad más alta.

Una vez que se llena una posición, ir a la siguiente posición. Si la posición comparte un grupo con una posición ya asignado, evitarlo, iteración a través de todas las posiciones hasta que se pueden asignar tantas posiciones como se puede en el día 1. A continuación, incrementar el contador de días y repita para el día 2. Esto debe darle una asignación máxima (no estoy seguro de como máximo) para todos los puestos de trabajo.

Consejo: cuando se mueve un miembro hasta el final de la lista de miembros, para evitar tener que recorrer la lista, mantenga una referencia al fin - para la siguiente posición, tiene que empezar desde el principio de todos modos, así que no hay punto de pasar por toda la cosa.

Respondida el 02/01/2010 a las 18:16
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more