Resuelve un problema de programación de turnos fijo a partir del SolveShiftSchedulingRequest
dado asignando a los empleados turnos para que las horas de se maximizan las preferencias de programación y se minimizan los incumplimientos de las restricciones de programación.
Solicitud HTTP
POST https://optimization.googleapis.com/v1/scheduling:solveShiftScheduling
La URL usa la sintaxis de la transcodificación gRPC.
Cuerpo de la solicitud
El cuerpo de la solicitud contiene datos con la siguiente estructura:
Representación JSON |
---|
{ "requestId": string, "solveParameters": { object ( |
Campos | |
---|---|
requestId |
ID de solicitud o problema. |
solveParameters |
Parámetros para controlar una única solución del problema. |
employees[] |
Se programarán todos los empleados disponibles. |
shifts[] |
Todos los turnos para definir el cronograma. |
coverageRequirements[] |
Requisitos de cobertura para todo el horizonte de planificación. Estas especifican la cantidad de empleados que deben cumplir cada función, o que poseen una habilidad, durante un período o una lista de IDs de turnos. Todos los requisitos de cobertura deben especificarse con un período o con una lista de los IDs de los cambios (pero no con ambos). Los períodos (si se proporcionan) de los requisitos de cobertura no pueden superponerse para cada ubicación determinada. El nivel de prioridad predeterminado para cada una de estas restricciones es |
roleIds[] |
Lista de todos los puestos posibles en la fuerza laboral. Cada empleado debe tener al menos una función que se le pueda asignar para un turno. Un rol se refiere a una asignación de trabajo específica durante un turno (es decir, enfermero registrado, chef ejecutivo, camarero, etcétera). Cuando se asigna un turno a un empleado, también se le asigna una función específica. |
skillIds[] |
Lista de todas las habilidades posibles en la fuerza laboral. Una habilidad se refiere a cualquier calificación adicional que un empleado pueda tener y que no esté relacionada con un trabajo asignable específico (es decir, certificaciones, idiomas que se hablan, etc.). Esta lista puede estar vacía. Cuando se asigna un turno a un empleado, debe cumplir con todas las habilidades necesarias para ese turno. |
locationIds[] |
Lista de todas las ubicaciones posibles para el conjunto de turnos en el horario. Esta lista puede estar vacía. Especificar diferentes ubicaciones puede ser útil cuando, por ejemplo, un gerente de enfermería quiere programar muchas sesiones de enfermería en diferentes unidades de un hospital o, por ejemplo, el gerente de un hotel quiere reservar empleados en varios hoteles. |
budgetRequirements[] |
Especificación de presupuesto para el problema de programación. El nivel de prioridad predeterminado para cada uno de estos requisitos es |
assignmentsHint[] |
Cambia las asignaciones para usarlas como una solución tentativa (también conocida como sugerencia de solución) para el problema de programación. Las sugerencias de asignación se ignoran si la asignación contradice un cambio no asignable o una solicitud de programación. |
Cuerpo de la respuesta
Respuesta para la API de programación del personal. Para cada respuesta, el shiftAssignments
estará vacío si el solutionStatus
que se muestra es NOT_SOLVED_DEADLINE_EXCEEDED
o INFEASIBLE
. Si el solutionStatus
que se muestra es OPTIMAL
o FEASIBLE
, se muestra una asignación de cambio válida en shiftAssignments
. Para una asignación de cambio válida, se cumplen las siguientes propiedades:
- Cada ID de empleado está incluido en el conjunto de empleados que se proporciona en la solicitud.
- Cada ID de rol asignado al empleado está incluido en el conjunto de ID de rol para el empleado dado.
- Cada ID de cambio está contenido en el conjunto de cambios indicado en la solicitud.
- Cada ID de turno no es uno de los ID de turno no asignables para el empleado dado.
- Un empleado nunca tendrá asignado dos turnos que se superpongan.
- Para la programación determinada, no se infringe ninguna de las restricciones o solicitudes con el nivel de prioridad
PRIORITY_MANDATORY
.
Si se ejecuta correctamente, el cuerpo de la respuesta contendrá datos con la siguiente estructura:
Representación JSON |
---|
{ "requestId": string, "solutionStatus": enum ( |
Campos | |
---|---|
requestId |
El ID de la solicitud con la que se asocia esta respuesta. |
solutionStatus |
Estado de la solución que se muestra. Si la solución no es ÓPTIMA ni FEASIBLE, es posible que otros campos de este protocolo estén vacíos. Si el estado es NOT_SOLVED_DEADLINE_EXCEEDED, se alcanzó el límite de tiempo sin encontrar una solución factible o determinar si existe una. Las solicitudes pueden ser inviables si no se pueden satisfacer todas las restricciones del nivel de prioridad OBLIGATORIO. |
shiftAssignments[] |
Lista de todas las asignaciones. Cada |
statusMessage |
Si |
SolveParameters
Son parámetros que controlan una sola solución al problema de la programación de turnos.
Representación JSON |
---|
{ "timeLimit": string } |
Campos | |
---|---|
timeLimit |
Tiempo máximo que el agente de resolución debería dedicar al problema. Si no se establece, el valor predeterminado es 1 minuto. Este valor no es un límite estricto y no tiene en cuenta la sobrecarga de comunicación. Es posible que la latencia esperada para resolver el problema exceda un poco este valor. Una duración en segundos con hasta nueve dígitos decimales, que terminan en “ |
Empleado
Se programará a un empleado del personal.
Representación JSON |
---|
{ "id": string, "roleIds": [ string ], "skillIds": [ string ], "shiftPreferences": [ { object ( |
Campos | |
---|---|
id |
ID único asignado a este empleado. |
roleIds[] |
Son los IDs de función que puede realizar este empleado. Se debe especificar al menos un rol. Cuando se asigna un turno a un empleado, también se le asigna un solo rol de esta lista. Se le puede asignar al empleado a diferentes roles durante el período de programación. |
skillIds[] |
Los IDs de habilidad que posee este empleado. Esta lista puede estar vacía. Cuando se asigna un turno a un empleado, usa cualquier subconjunto de las habilidades enumeradas aquí para cubrir los requisitos de habilidades a lo largo del turno asignado. |
shiftPreferences[] |
Cambiar las preferencias de este empleado. Los turnos especificados aquí representan cambios a los que el empleado preferiría asignarse durante el período de programación. Los IDs de cambio especificados en |
schedulingConstraints[] |
Lista de restricciones de horario para este empleado. El nivel de prioridad predeterminado para cada una de estas restricciones es |
resourceConstraints[] |
Cualquier restricción de programación adicional que no se especifique en |
shiftRequests[] |
Lista de solicitudes de turnos para el empleado. La solicitud puede ser para que se asigne o no a un empleado en turnos específicos. Cualquier asignación de programación fija para el empleado se puede representar con un |
hourlyContract |
Contrato que especifica las tarifas regulares y por horas extra para el empleado. |
ShiftPreference
Una preferencia numérica para un ID de cambio en particular.
Representación JSON |
---|
{ "shiftId": string, "preference": integer } |
Campos | |
---|---|
shiftId |
Es el ID del cambio para el que se especifica la preferencia. |
preference |
Los valores de preferencia más altos indican un cambio más deseable. |
SchedulingConstraint
Restricción de horario específica para un empleado en particular. La restricción especificada solo se aplica durante el intervalo [startDateTime,
endDateTime)
determinado.
Representación JSON |
---|
{ "priority": enum ( |
Campos | |
---|---|
priority |
Nivel de prioridad para esta restricción de programación. La prioridad predeterminada para todas las restricciones de programación es |
startDateTime |
Es la hora de inicio en la que se aplica esta restricción de programación (incluida). |
endDateTime |
Es la hora de finalización en la que se aplica esta restricción de programación (exclusivo). |
Campo de unión type . El tipo de restricción que se especifica. Cada restricción solo se aplica dentro del período especificado anteriormente. Las direcciones (type ) solo pueden ser una de las siguientes opciones: |
|
minimumMinutes |
Cantidad mínima de minutos que el empleado puede trabajar. Si se asigna al empleado un turno que se superpone (total o parcialmente) con la ventana de tiempo, la cantidad de minutos que el turno se superpone con la ventana de tiempo se incluye en este recuento. |
maximumMinutes |
Cantidad máxima de minutos que el empleado puede trabajar en la ventana de tiempo. Si se asigna al empleado un turno que se superpone (total o parcialmente) con la ventana de tiempo, la cantidad de minutos que el turno se superpone con la ventana de tiempo se incluye en este recuento. |
minimumConsecutiveWorkDays |
Cantidad mínima de días consecutivos en los que puede trabajar el empleado. Un empleado trabaja un día específico si se le asigna un turno que comienza durante ese día. Cualquier turno al que se asigne el empleado y que comience en el período se incluye en este recuento. |
maximumConsecutiveWorkDays |
Cantidad máxima de días consecutivos en los que puede trabajar el empleado Un empleado trabaja un día específico si se le asigna un turno que comienza durante ese día. Cualquier turno al que se asigne el empleado y que comience en el período se incluye en este recuento. |
minimumShiftCount |
Cantidad mínima de turnos que puede realizar el empleado. Este recuento incluye cualquier cambio al que se asigne el empleado y que se superponga completamente con el período. |
maximumShiftCount |
Cantidad máxima de turnos que puede trabajar el empleado Este recuento incluye cualquier cambio al que se asigne el empleado y que se superponga completamente con el período. |
minimumRestMinutes |
Cantidad mínima de minutos que el empleado debe descansar después del final de un turno antes de que se lo asigne a otro. Esta restricción se aplica a cada par de turnos que se incluyen por completo en [ |
Prioridad
El nivel de prioridad para cualquier restricción en el horario de un empleado o los requisitos de cobertura. Estos incluyen SchedulingConstraint
, ResourceConstraint
, ShiftRequest
y CoverageRequirement
. Debido a que puede haber restricciones en conflicto, no siempre es posible satisfacer todas. Por lo tanto, cada tipo de restricción tiene una prioridad (determinada por el usuario o predeterminada) que informa al solucionador sobre la importancia relativa de todas las restricciones otorgadas a un programa completo.
Enumeraciones | |
---|---|
PRIORITY_UNSPECIFIED |
Nivel de prioridad desconocido. |
PRIORITY_LOW |
El nivel de prioridad más bajo. Las restricciones con esta prioridad son menos importantes que las demás. Son los primeros en considerarse una infracción si no se encuentra una solución viable. |
PRIORITY_MEDIUM |
Nivel de prioridad medio. Las restricciones con esta prioridad son más importantes que las que tienen prioridad PRIORITY_LOW , pero menos importantes que las PRIORITY_HIGH . Si no se puede encontrar una solución factible después de relajar todas las restricciones con prioridad PRIORITY_LOW , las restricciones con prioridad PRIORITY_MEDIUM se consideran a continuación para el incumplimiento. |
PRIORITY_HIGH |
El nivel de prioridad más alto. Las restricciones con este nivel de prioridad son las más importantes. Son las últimas que se consideran por incumplimiento si no se puede encontrar una solución factible después de flexibilizar las restricciones de los niveles de prioridad más bajos. |
PRIORITY_MANDATORY |
Nivel de prioridad que representa algo que el solucionador no puede incumplir. Si el solucionador muestra SolutionStatus.INFEASIBLE , puede deberse a demasiadas restricciones de PRIORITY_MANDATORY . |
ResourceConstraint
Restricción general que limita la cantidad de un “recurso” determinado utilizado por un empleado. Esta es una versión abstracta del SchedulingConstraint
más específico que es más flexible para el usuario. Muchas restricciones de programación que no se pueden especificar en SchedulingConstraint.type
se pueden especificar con este mensaje en su lugar.
Representación JSON |
---|
{
"priority": enum ( |
Campos | |
---|---|
priority |
Nivel de prioridad de esta restricción de recursos. La prioridad predeterminada para todas las restricciones de recursos es |
resourceUsages |
Cantidad de recursos que usan los turnos. Por ejemplo, si esta restricción se aplica a las horas mínimas y máximas que trabajó un empleado durante una semana específica, este mapa contendrá los cambios que se producen en esa semana y la duración de cada cambio en horas. Es un objeto que contiene una lista de pares |
minimumResourceUsage |
Uso mínimo de recursos para que se cumpla una restricción de recursos. |
maximumResourceUsage |
Uso máximo de recursos para que se cumpla una restricción de recursos. |
ShiftRequest
La solicitud de un empleado de que se le asigne o no que se asigne a turnos específicos.
Representación JSON |
---|
{ "priority": enum ( |
Campos | |
---|---|
priority |
Nivel de prioridad de esta solicitud de programación. La prioridad predeterminada para todas las solicitudes de programación es |
shiftIds[] |
Los IDs de los cambios de la solicitud de programación. |
type |
Tipo de solicitud, p.ej., si la solicitud se asignó o no al conjunto de cambios. |
WorkStatus
Si un empleado está trabajando o no.
Enumeraciones | |
---|---|
WORK_STATUS_UNSPECIFIED |
Estado de trabajo desconocido. |
STATUS_WORK |
Estado que representa a un empleado que trabaja. |
STATUS_NOT_WORK |
Estado que representa a un empleado que no trabaja |
HourlyContract
Especifica una tarifa por hora base, diferenciales de tarifas y multiplicadores de horas extras para determinar la remuneración de un empleado. Ten en cuenta que las reglamentaciones en distintas partes podrían requerir un cálculo diferente de la compensación por horas extra. La herramienta de resolución aproxima la compensación por tiempo extra para minimizar un costo total o alcanzar un presupuesto (consulta BudgetRequirement
). No está diseñada como una herramienta para calcular la nómina.
Representación JSON |
---|
{
"baseHourlyRate": number,
"hourlyRateShiftDifferentials": {
string: number,
...
},
"overtimePeriods": [
{
object ( |
Campos | |
---|---|
baseHourlyRate |
La remuneración por trabajar una hora no extrahora. Si se aplican varias tarifas al empleado, se aplican diferenciales de tarifas en relación con esta tarifa base por hora. Además, si hay varias tarifas, la tarifa base por hora debe ser la mínima de estas. |
hourlyRateShiftDifferentials |
La diferencial de tarifas por hora, que se paga sobre el Es un objeto que contiene una lista de pares |
overtimePeriods[] |
Una lista de todos los períodos para los que se debe calcular el tiempo extra Estos períodos no deben superponerse. |
OvertimePeriod
Es un período fijo y recurrente (generalmente de 168 horas o siete períodos consecutivos de 24 horas) que se usa para determinar el importe de la remuneración por horas extras. Cada período tiene un multiplicador de horas extras (p.ej., 1.5) en relación con la baseHourlyRate
y un límite en la cantidad de horas que se consideran trabajos normales (no extraordinarios) Cualquier cambio que se superponga con los períodos startDateTime
(inclusivo) y endDateTime
(exclusivo) se contabiliza en la cantidad total de horas trabajadas en el período. Si la superposición es parcial, solo se contarán las horas que se superponen.
Representación JSON |
---|
{ "overtimeMultiplier": number, "startDateTime": { object ( |
Campos | |
---|---|
overtimeMultiplier |
Multiplicador para calcular la tarifa por hora extra (debe ser mayor o igual que 1.0) Por lo general, la tarifa por hora extra con el tiempo se calcula como |
startDateTime |
Es la hora de inicio del período extra. Si un cambio se superpone en este período, las horas de ese cambio se contarán desde |
endDateTime |
Es la hora de finalización del período extra. Si un cambio se superpone en este período, las horas de ese cambio se contarán hasta |
maximumRegularHours |
Cantidad máxima de horas laborales que se pagan a una tarifa regular (que no pertenece a horas extras). Esta cantidad debe ser positiva. |
Mayúsculas
Un turno especifica una ventana de tiempo fija en la que pueden trabajar los empleados.
Representación JSON |
---|
{ "id": string, "locationId": string, "startDateTime": { object ( |
Campos | |
---|---|
id |
Es un ID único asignado a este cambio. |
locationId |
Es el ID de ubicación en el que se realiza este cambio. Este campo puede estar vacío. |
startDateTime |
La hora de inicio del cambio (inclusive). |
endDateTime |
La hora de finalización del cambio (exclusivo). Actualmente, la resolución solo permite cambios de menos de 24 horas de duración. |
breakRules[] |
Una lista de las reglas de incumplimiento que ocurren durante el cambio. A los empleados que realizan este turno se les asigna un descanso por |
BreakRule
Es una regla que determina cuándo puede comenzar una pausa dentro de un cambio y su duración. La lista de todas las pausas posibles que se consideran se determina en incrementos de ruleIncrementMinutes
. Por ejemplo, si una regla de pausa modela una pausa de 30 minutos que puede comenzar entre las 10:00 y las 11:00, y el incremento de la regla es de 20 minutos, la lista de pausas que se consideran es la siguiente: [10:00, 10:30], [10:20, 10:50], [10:10, 11:10], [10:10, 11:10]
Representación JSON |
---|
{ "earliestStartTime": { object ( |
Campos | |
---|---|
earliestStartTime |
La hora de inicio más temprana de la pausa (inclusive). Solo se pueden configurar |
latestStartTime |
La hora de inicio más reciente de la pausa (incluida). Solo se pueden configurar |
durationMinutes |
Duración de la pausa en minutos. |
ruleIncrementMinutes |
[Opcional] Incremento de tiempo en minutos para todas las pausas que se pueden considerar en esta regla de pausa. Si no se establece, el valor predeterminado es |
CoverageRequirement
Un requisito de cobertura especifica la cantidad de empleados necesarios para un conjunto de roles o habilidades durante un período en particular y en una ubicación determinada. No se pueden superponer los intervalos de DateTime en una ubicación en particular. Como alternativa, se puede proporcionar una lista de IDs de turno en lugar de un período y una ubicación. Solo los empleados que pueden asignarse a la función específica (o que poseen la habilidad específica) pueden cumplir este requisito.
Para un rol o una habilidad determinados, el requisito de cobertura se cumple cuando al menos targetEmployeeCount
de empleados trabajan en todo momento del período (o para cada turno en shiftIds
). Por el contrario, se incumple el requisito de cobertura si en algún momento del período (o para cualquiera de los turnos en shiftIds
), hay menos de targetEmployeeCount
empleados trabajando durante el período. La cantidad de empleados que trabajan más que la targetEmployeeCount
sigue cumpliendo el requisito, pero el solucionador minimiza el exceso de personal.
Representación JSON |
---|
{ "startDateTime": { object ( |
Campos | |
---|---|
startDateTime |
Es la hora de inicio del requisito de cobertura (incluida). Si se configura, |
endDateTime |
La hora de finalización del requisito de cobertura (exclusivo). Si se configura, |
locationId |
Ubicación en la que se necesitan los empleados. |
shiftIds[] |
Si se establecen, los requisitos de rol y habilidad se aplican individualmente a cada ID de turno en esta lista. Si ShiftIds no está vacío, |
roleRequirements[] |
Cantidad requerida de empleados que se asignarán a los roles especificados durante el período. Se debe proporcionar un |
skillRequirements[] |
Cantidad requerida de empleados con las habilidades especificadas que están asignados a turnos durante el período establecido. Se debe proporcionar una |
RoleRequirement
Cantidad requerida de empleados que se asignarán a la función especificada durante el período.
Representación JSON |
---|
{
"roleId": string,
"targetEmployeeCount": integer,
"priority": enum ( |
Campos | |
---|---|
roleId |
Es el ID de función del requisito. |
targetEmployeeCount |
Cantidad deseada de empleados asignados a la función durante el período establecido. |
priority |
Nivel de prioridad para esta restricción de requisitos. La prioridad predeterminada para todas las restricciones de recursos es |
SkillRequirement
Cantidad requerida de empleados que trabajan durante el período y tienen la habilidad especificada.
Representación JSON |
---|
{
"skillId": string,
"targetEmployeeCount": integer,
"priority": enum ( |
Campos | |
---|---|
skillId |
Es el ID de habilidad del requisito. |
targetEmployeeCount |
Número deseado de empleados con una habilidad determinada que trabajan durante ese período. |
priority |
Nivel de prioridad para esta restricción de requisitos. La prioridad predeterminada para todas las restricciones de recursos es |
BudgetRequirement
Requisitos de presupuesto para un intervalo determinado.
Representación JSON |
---|
{ "totalBudget": number, "startDateTime": { object ( |
Campos | |
---|---|
totalBudget |
Es el presupuesto total para el intervalo determinado. Se debe proporcionar un presupuesto total si la prioridad es Si no estableces |
startDateTime |
Es la hora de inicio del momento en que se aplica este presupuesto. Si no se especifica la hora de inicio, se establece como la hora de inicio más temprana de todos los cambios. |
endDateTime |
Es la hora de finalización cuando se aplica este presupuesto. Si no se especifica una hora de finalización, se establece como la última hora de finalización de todos los cambios. |
priority |
Nivel de prioridad para cumplir con el requisito de presupuesto durante el período especificado. La prioridad predeterminada es Ten en cuenta que, si esta prioridad es mayor que otras prioridades de restricción y si |
ShiftAssignment
Un empleado debe asignar un rol por turnos.
Representación JSON |
---|
{
"employeeId": string,
"shiftId": string,
"roleId": string,
"breaks": [
{
object ( |
Campos | |
---|---|
employeeId |
El ID del empleado que se asigna. |
shiftId |
El ID del turno asignado al empleado. |
roleId |
Es el ID de rol al que se asignó el empleado para el turno. |
breaks[] |
Lista de pausas para esta asignación de turno. |
Receso
Un período en el que un empleado interrumpe su trabajo durante un turno.
Representación JSON |
---|
{
"startDateTime": {
object ( |
Campos | |
---|---|
startDateTime |
Hora de inicio de un descanso. |
durationMinutes |
Duración de la pausa en minutos. |
SolutionStatus
Estado de la solución (es decir, un programa) que se proporciona en la respuesta de una resolución
Enumeraciones | |
---|---|
SOLUTION_STATUS_UNSPECIFIED |
Estado sin especificar para la respuesta. |
FEASIBLE |
El programa que se muestra es factible, pero puede no ser óptimo. |
OPTIMAL |
El programa que se muestra es óptimo. |
INFEASIBLE |
No existe un cronograma factible para las restricciones dadas. La herramienta de resolución puede mostrar este valor si no se puede satisfacer algún subconjunto de las restricciones con el nivel de prioridad PRIORITY_MANDATORY . |
NOT_SOLVED |
No se encontró ningún programa. |
NOT_SOLVED_DEADLINE_EXCEEDED |
No se encontró ningún programa dentro del límite de tiempo establecido. |