Risolve un problema fisso di programmazione dei turni rispetto a un determinato SolveShiftSchedulingRequest
assegnando i dipendenti a turni in modo che le preferenze di pianificazione dei dipendenti vengano massimizzate e le violazioni dei vincoli di pianificazione siano ridotte al minimo.
Richiesta HTTP
POST https://optimization.googleapis.com/v1/scheduling:solveShiftScheduling
L'URL utilizza la sintassi di transcodifica gRPC.
Corpo della richiesta
Il corpo della richiesta contiene dati con la seguente struttura:
Rappresentazione JSON |
---|
{ "requestId": string, "solveParameters": { object ( |
Campi | |
---|---|
requestId |
Problema o ID richiesta. |
solveParameters |
Parametri per controllare una singola risoluzione del problema. |
employees[] |
Tutti i dipendenti disponibili da pianificare. |
shifts[] |
Tutti i turni per definire la pianificazione. |
coverageRequirements[] |
Requisiti di copertura per l'intero orizzonte di pianificazione. Specifica il numero di dipendenti che devono svolgere ogni ruolo, o possedere una competenza, durante una finestra temporale o un elenco di ID turni. Tutti i requisiti di copertura devono essere specificati con finestre temporali o un elenco di ID turni (ma non entrambi). Le finestre temporali (se disponibili) per i requisiti di copertura non possono sovrapporsi per ogni località specificata. Il livello di priorità predefinito per ciascuno di questi vincoli è |
roleIds[] |
Elenco di tutti i possibili ruoli della forza lavoro. Ogni dipendente deve avere almeno un ruolo a cui può essere assegnato per un turno. Un ruolo fa riferimento a un incarico di lavoro specifico durante un turno (ad es. infermiera registrata, executive chef, cameriere e così via). Quando a un dipendente viene assegnato un turno, gli viene anche assegnato un singolo ruolo specifico. |
skillIds[] |
Elenco di tutte le possibili competenze del mondo del lavoro. Per competenza si intende qualsiasi qualifica aggiuntiva che un dipendente può avere e che non riguardano uno specifico lavoro assegnabile (ad esempio certificazioni, lingue parlate e così via). L'elenco può essere vuoto. Quando a un dipendente viene assegnato un turno, deve soddisfare tutte le competenze necessarie per quel turno. |
locationIds[] |
Elenco di tutte le posizioni possibili per la serie di turni nella programmazione. L'elenco può essere vuoto. Specificare località diverse può essere utile quando, ad esempio, un responsabile infermieristico vuole programmare il numero di infermieri in diverse unità di un ospedale o, per un altro esempio, un responsabile di hotel vuole pianificare i dipendenti in più hotel. |
budgetRequirements[] |
Specifica del budget per il problema di pianificazione. Il livello di priorità predefinito per ciascuno di questi requisiti è |
assignmentsHint[] |
Sposta le assegnazioni da usare come soluzione provvisoria (ovvero suggerimento per la soluzione) al problema di pianificazione. I suggerimenti dei compiti vengono ignorati se il compito contraddice un turno non assegnabile o una richiesta di programmazione. |
Corpo della risposta
Risposta per l'API di pianificazione della forza lavoro. Per ogni risposta, il shiftAssignments
sarà vuoto se il valore solutionStatus
restituito è NOT_SOLVED_DEADLINE_EXCEEDED
o INFEASIBLE
. Se il solutionStatus
restituito è OPTIMAL
o FEASIBLE
, viene restituita un'assegnazione di turno valida in shiftAssignments
. Per un'assegnazione di spostamento valida, valgono le seguenti proprietà:
- Ogni ID dipendente è incluso nell'insieme di dipendenti indicato nella richiesta.
- Ogni ID ruolo assegnato al dipendente è contenuto nell'insieme di ID ruolo del dipendente specificato.
- Ogni ID turno è incluso nell'insieme di turni specificati nella richiesta.
- Ogni ID turno non è uno degli ID turno non assegnabili per un determinato dipendente.
- A un dipendente non verranno mai assegnati due turni sovrapposti.
- Per la pianificazione specificata, non viene violato nessuno dei vincoli o delle richieste con livello di priorità
PRIORITY_MANDATORY
.
In caso di esito positivo, il corpo della risposta contiene dati con la seguente struttura:
Rappresentazione JSON |
---|
{ "requestId": string, "solutionStatus": enum ( |
Campi | |
---|---|
requestId |
L'ID della richiesta a cui è associata questa risposta. |
solutionStatus |
Stato della soluzione restituita. Se la soluzione non è FEASIBLE o OPTIMAL, gli altri campi di questo protocollo potrebbero essere vuoti. Se lo stato è NOT_SOLVED_DEADLINE_EXCEEDED, il limite di tempo è stato raggiunto senza trovare una soluzione utilizzabile o determinare se esiste una soluzione fattibile. Le richieste potrebbero non essere soddisfatte se non possono essere soddisfatti tutti i vincoli del livello di priorità MANDATORY. |
shiftAssignments[] |
Elenco di tutti i compiti. Ogni |
statusMessage |
Se |
SolveParameters
Parametri che controllano una singola risoluzione del problema di pianificazione dei turni.
Rappresentazione JSON |
---|
{ "timeLimit": string } |
Campi | |
---|---|
timeLimit |
Tempo massimo che il risolutore deve dedicare al problema. Se non viene configurato, il valore predefinito è 1 minuto. Questo valore non è un limite fisso e non tiene conto del sovraccarico di comunicazione. La latenza prevista per risolvere il problema potrebbe superare leggermente questo valore. Una durata in secondi con un massimo di nove cifre frazionarie, che termina con " |
Dipendente
Un dipendente del personale da definire.
Rappresentazione JSON |
---|
{ "id": string, "roleIds": [ string ], "skillIds": [ string ], "shiftPreferences": [ { object ( |
Campi | |
---|---|
id |
ID univoco assegnato a questo dipendente. |
roleIds[] |
ID ruolo che questo dipendente può eseguire. Deve essere specificato almeno un ruolo. Quando a un dipendente viene assegnato un turno, viene anche assegnato un singolo ruolo di questo elenco. Al dipendente possono essere assegnati ruoli diversi durante la finestra di programmazione. |
skillIds[] |
ID delle competenze di cui dispone questo dipendente. L'elenco può essere vuoto. Quando un dipendente viene assegnato a un turno, utilizza un sottoinsieme delle competenze qui elencate per soddisfare i requisiti di competenza per tutta la durata del turno assegnato. |
shiftPreferences[] |
Cambia le preferenze di questo dipendente. I turni specificati qui rappresentano i turni a cui il dipendente preferirebbe essere assegnato durante la finestra di programmazione. Gli ID spostamento specificati in |
schedulingConstraints[] |
Elenco dei vincoli di pianificazione per questo dipendente. Il livello di priorità predefinito per ciascuno di questi vincoli è |
resourceConstraints[] |
Eventuali altri vincoli di pianificazione non specificati in |
shiftRequests[] |
Elenco delle richieste di turno per il dipendente. La richiesta può riguardare un dipendente da assegnare o non assegnare a turni specifici. Qualsiasi compito con programmazione fissa per il dipendente può essere rappresentato con un |
hourlyContract |
Contratto che specifica tariffe orarie regolari e straordinari per il dipendente. |
ShiftPreference
Una preferenza numerica per un determinato ID spostamento.
Rappresentazione JSON |
---|
{ "shiftId": string, "preference": integer } |
Campi | |
---|---|
shiftId |
ID spostamento per il quale è specificata la preferenza. |
preference |
Valori di preferenza maggiori indicano uno spostamento più desiderabile. |
SchedulingConstraint
Vincolo di programmazione specifico per un determinato dipendente. Il vincolo specificato viene applicato solo durante l'intervallo specificato [startDateTime,
endDateTime)
.
Rappresentazione JSON |
---|
{ "priority": enum ( |
Campi | |
---|---|
priority |
Livello di priorità per questo vincolo di pianificazione. La priorità predefinita per tutti i vincoli di pianificazione è |
startDateTime |
L'ora di inizio di applicazione di questo vincolo di pianificazione (inclusa). |
endDateTime |
L'ora di fine (esclusiva) di fine dell'applicazione di questo vincolo di pianificazione. |
Campo di unione type . Il tipo di vincolo specificato. Ogni vincolo viene applicato solo nell'intervallo di tempo specificato in precedenza. type può essere solo uno dei seguenti: |
|
minimumMinutes |
Numero minimo di minuti che il dipendente può lavorare. Se al dipendente viene assegnato un turno che si sovrappone (completamente o parzialmente) alla finestra temporale, il numero di minuti in cui il turno si sovrappone alla finestra temporale viene incluso in questo conteggio. |
maximumMinutes |
Numero massimo di minuti che il dipendente può lavorare nella finestra temporale. Se al dipendente viene assegnato un turno che si sovrappone (completamente o parzialmente) alla finestra temporale, il numero di minuti in cui il turno si sovrappone alla finestra temporale viene incluso in questo conteggio. |
minimumConsecutiveWorkDays |
Numero minimo di giorni consecutivi in cui il dipendente può lavorare. Un dipendente lavora in un giorno specifico se viene assegnato a un turno che inizia in quel giorno. Qualsiasi turno assegnato al dipendente che inizia nell'intervallo di tempo è incluso in questo conteggio. |
maximumConsecutiveWorkDays |
Numero massimo di giorni consecutivi in cui un dipendente può lavorare. Un dipendente lavora in un giorno specifico se viene assegnato a un turno che inizia in quel giorno. Qualsiasi turno assegnato al dipendente che inizia nell'intervallo di tempo è incluso in questo conteggio. |
minimumShiftCount |
Numero minimo di turni a cui può lavorare il dipendente. Qualsiasi turno a cui è assegnato il dipendente che si sovrappone completamente alla finestra temporale è incluso in questo conteggio. |
maximumShiftCount |
Numero massimo di turni a cui può lavorare il dipendente. Qualsiasi turno a cui è assegnato il dipendente che si sovrappone completamente alla finestra temporale è incluso in questo conteggio. |
minimumRestMinutes |
Numero minimo di minuti in cui il dipendente deve riposare dopo la fine di un turno prima di essere assegnato a un altro turno. Questo vincolo si applica a ogni coppia di spostamenti completamente inclusa in [ |
Priorità
Il livello di priorità di qualsiasi vincolo nell'orario di lavoro di un dipendente o nei requisiti di copertura. Questi includono SchedulingConstraint
, ResourceConstraint
, ShiftRequest
e CoverageRequirement
. Poiché potrebbero esserci vincoli in conflitto, non è sempre possibile soddisfare tutti i vincoli. Pertanto, ogni tipo di vincolo ha una priorità (dall'utente o predefinita) che comunica al risolutore l'importanza relativa di tutti i vincoli assegnati a una pianificazione completa.
Enum | |
---|---|
PRIORITY_UNSPECIFIED |
Livello di priorità sconosciuto. |
PRIORITY_LOW |
Il livello di priorità più basso. I vincoli con questa priorità sono meno importanti degli altri vincoli. Sono le prime a essere prese in considerazione per le violazioni qualora non sia possibile trovare una soluzione praticabile. |
PRIORITY_MEDIUM |
Livello di priorità medio. I vincoli con questa priorità sono più importanti dei vincoli con priorità PRIORITY_LOW , ma meno importanti dei vincoli con priorità PRIORITY_HIGH . Se non viene trovata una soluzione fattibile dopo aver allentato tutti i vincoli con priorità PRIORITY_LOW , i vincoli con priorità PRIORITY_MEDIUM vengono considerati successivamente per la violazione. |
PRIORITY_HIGH |
Il livello di priorità più alto. I vincoli con questo livello di priorità sono i più importanti. Sono gli ultimi da considerare per violazione se non è possibile trovare una soluzione fattibile dopo aver allentato i vincoli dei livelli di priorità inferiori. |
PRIORITY_MANDATORY |
Livello di priorità che rappresenta qualcosa che non può essere violato dal risolutore. Se il risolutore restituisce SolutionStatus.INFEASIBLE , la causa potrebbe essere un numero eccessivo di vincoli PRIORITY_MANDATORY . |
ResourceConstraint
Un vincolo generale che limita la quantità di una determinata "risorsa" utilizzata da un dipendente. Questa è una versione astratta del SchedulingConstraint
più specifico, più flessibile per l'utente. Molti vincoli di pianificazione che non possono essere specificati in SchedulingConstraint.type
possono essere specificati utilizzando questo messaggio.
Rappresentazione JSON |
---|
{
"priority": enum ( |
Campi | |
---|---|
priority |
Livello di priorità di questo vincolo di risorse. La priorità predefinita per tutti i vincoli delle risorse è |
resourceUsages |
Quantità di risorse utilizzate dai turni. Ad esempio, se questo vincolo si applica al numero minimo e massimo di ore lavorate da un dipendente in una settimana specifica, questa mappa conterrà i turni che si verificano in quella settimana e la durata di ogni turno in ore. Un oggetto contenente un elenco di |
minimumResourceUsage |
Utilizzo minimo delle risorse per soddisfare un vincolo di risorse. |
maximumResourceUsage |
Utilizzo massimo delle risorse per soddisfare un vincolo di risorse. |
ShiftRequest
Richiesta di un dipendente di essere assegnato o di non essere assegnato a turni specifici.
Rappresentazione JSON |
---|
{ "priority": enum ( |
Campi | |
---|---|
priority |
Livello di priorità di questa richiesta di pianificazione. La priorità predefinita per tutte le richieste di pianificazione è |
shiftIds[] |
Gli ID turno della richiesta di pianificazione. |
type |
Tipo di richiesta, ad esempio se la richiesta è assegnata o meno alla serie di turni. |
WorkStatus
Se un dipendente lavora o meno.
Enum | |
---|---|
WORK_STATUS_UNSPECIFIED |
Stato del lavoro sconosciuto. |
STATUS_WORK |
Stato che rappresenta un dipendente funzionante. |
STATUS_NOT_WORK |
Stato che rappresenta un dipendente non lavorativo. |
HourlyContract
Specifica una tariffa oraria di base, le differenze di tariffa e i moltiplicatori delle ore di lavoro straordinario per determinare la retribuzione per un dipendente. Tieni presente che le normative in vigore in luoghi diversi potrebbero richiedere un calcolo diverso della retribuzione degli straordinari. Il risolutore approssima il compenso straordinario per minimizzare un proxy del costo totale o soddisfare un budget (vedi BudgetRequirement
). Non è stato pensato come uno strumento per calcolare la busta paga.
Rappresentazione JSON |
---|
{
"baseHourlyRate": number,
"hourlyRateShiftDifferentials": {
string: number,
...
},
"overtimePeriods": [
{
object ( |
Campi | |
---|---|
baseHourlyRate |
Il compenso per aver lavorato un'ora senza straordinari. Se al dipendente vengono applicate più tariffe, le differenze di tariffa vengono applicate in relazione a questa tariffa oraria di base. Inoltre, se sono presenti più tariffe, la tariffa oraria di base deve essere quella minima. |
hourlyRateShiftDifferentials |
Il differenziale di tariffa oraria pagato in aggiunta a Un oggetto contenente un elenco di |
overtimePeriods[] |
Un elenco di tutti i periodi per i quali è necessario calcolare il tempo straordinario. Questi periodi non devono sovrapporsi. |
OvertimePeriod
Periodo fisso e ricorrente (di solito di 168 ore o sette periodi consecutivi di 24 ore) utilizzato per determinare l'importo della retribuzione per gli straordinari. Ogni periodo ha un moltiplicatore dei tempi supplementari (ad es. 1,5) rispetto all'baseHourlyRate
e un limite al numero di ore da considerarsi come lavoro regolare (non straordinari). Qualsiasi spostamento che si sovrappone alla finestra temporale di startDateTime
(incluso) e endDateTime
(escluso) viene conteggiato ai fini del numero totale di ore lavorate nel periodo. Se la sovrapposizione è parziale, vengono conteggiate solo le ore sovrapposte.
Rappresentazione JSON |
---|
{ "overtimeMultiplier": number, "startDateTime": { object ( |
Campi | |
---|---|
overtimeMultiplier |
Moltiplicatore per calcolare la tariffa oraria del tempo di lavoro straordinario (deve essere maggiore o uguale a 1,0). La tariffa oraria per gli straordinari viene generalmente calcolata come |
startDateTime |
Ora di inizio del periodo di tempo straordinario. Se un turno si sovrappone a questo orario, le ore di tale turno vengono conteggiate a partire dal giorno |
endDateTime |
Ora di fine del periodo di tempo straordinario. Se un turno si sovrappone a questo orario, le ore di tale turno vengono conteggiate fino a |
maximumRegularHours |
Numero massimo di ore di lavoro retribuite con cadenza regolare (non straordinari). Questa quantità deve essere positiva. |
Maiusc
Un turno specifica una finestra temporale fissa in cui i dipendenti possono lavorare.
Rappresentazione JSON |
---|
{ "id": string, "locationId": string, "startDateTime": { object ( |
Campi | |
---|---|
id |
ID univoco assegnato a questo turno. |
locationId |
L'ID località in cui ha lavorato questo passaggio. Questo campo può essere vuoto. |
startDateTime |
L'ora di inizio del turno (inclusa). |
endDateTime |
L'ora di fine del turno (esclusa). Attualmente, il risolutore consente solo turni di durata inferiore a 24 ore. |
breakRules[] |
Un elenco di regole di interruzione applicate durante il turno. Ai dipendenti che eseguono questo passaggio viene assegnata una pausa per |
BreakRule
Una regola che determina quando può iniziare un'interruzione all'interno di un intervallo e la sua durata. L'elenco di tutte le possibili interruzioni prese in considerazione è determinato in incrementi di ruleIncrementMinutes
. Ad esempio, se una regola di interruzione modella un'interruzione di 30 minuti che può iniziare tra le 10:00 e le 11:00 e l'incremento della regola è di 20 minuti, l'elenco di interruzioni considerate sarà: [10:00, 10:30], [10:20, 10:50], [10:40], [11:10], [11:10]
Rappresentazione JSON |
---|
{ "earliestStartTime": { object ( |
Campi | |
---|---|
earliestStartTime |
La prima ora di inizio dell'interruzione (inclusa). Puoi impostare solo |
latestStartTime |
L'ultima ora di inizio dell'interruzione (inclusa). Puoi impostare solo |
durationMinutes |
Durata dell'interruzione in minuti. |
ruleIncrementMinutes |
[Facoltativo] Aumento di tempo in minuti per tutte le interruzioni che possono essere considerate in questa regola di interruzione. Se non viene configurato, il valore predefinito è |
CoverageRequirement
Un requisito di copertura specifica il numero di dipendenti richiesti per una serie di ruoli e/o competenze in un determinato periodo di tempo e in un luogo specifico. Gli intervalli di tipo DateTime di una determinata località non possono sovrapporsi. In alternativa, è possibile fornire un elenco di ID turno anziché una finestra temporale e una località. Solo i dipendenti a cui è possibile assegnare un determinato ruolo (o che possiedono la competenza specifica) possono soddisfare questo requisito.
Per un determinato ruolo e/o competenza, il requisito di copertura viene soddisfatto quando almeno targetEmployeeCount
numero di dipendenti lavora in ogni momento della finestra temporale (o per ogni turno in shiftIds
). Al contrario, il requisito di copertura viene violato se in qualsiasi momento dell'intervallo di tempo (o per uno qualsiasi dei turni in shiftIds
) c'è un numero di dipendenti che lavora meno di targetEmployeeCount
nell'intervallo di tempo. Un numero maggiore di dipendenti che lavorano rispetto a targetEmployeeCount
soddisfa il requisito, ma l'eccessivo numero di dipendenti è ridotto al minimo dal risolutore.
Rappresentazione JSON |
---|
{ "startDateTime": { object ( |
Campi | |
---|---|
startDateTime |
L'ora di inizio del requisito di copertura (inclusa). Se impostato, il campo |
endDateTime |
L'ora di fine del requisito di copertura (esclusa). Se impostato, il campo |
locationId |
Località in cui sono necessari i dipendenti. |
shiftIds[] |
Se impostato, i requisiti di ruolo e competenze vengono applicati singolarmente a ogni ID turno in questo elenco. Se i valori shiftId non sono vuoti, i campi |
roleRequirements[] |
Numero richiesto di dipendenti da assegnare ai ruoli specificati durante il periodo di tempo. È necessario specificare al massimo un |
skillRequirements[] |
Numero richiesto di dipendenti con le competenze specificate assegnate ai turni durante la finestra temporale. È necessario specificare al massimo un |
RoleRequirement
Numero richiesto di dipendenti da assegnare al ruolo specificato durante il periodo di tempo.
Rappresentazione JSON |
---|
{
"roleId": string,
"targetEmployeeCount": integer,
"priority": enum ( |
Campi | |
---|---|
roleId |
ID ruolo per il requisito. |
targetEmployeeCount |
Numero desiderato di dipendenti assegnati al ruolo durante il periodo di tempo. |
priority |
Livello di priorità per questo vincolo del requisito. La priorità predefinita per tutti i vincoli delle risorse è |
SkillRequirement
Numero richiesto di dipendenti che lavorano nell'intervallo di tempo e in possesso della competenza specificata.
Rappresentazione JSON |
---|
{
"skillId": string,
"targetEmployeeCount": integer,
"priority": enum ( |
Campi | |
---|---|
skillId |
ID competenza per il requisito. |
targetEmployeeCount |
Numero desiderato di dipendenti con la competenza specificata che lavorano durante il periodo di tempo selezionato. |
priority |
Livello di priorità per questo vincolo del requisito. La priorità predefinita per tutti i vincoli delle risorse è |
BudgetRequirement
Requisiti di budget per un determinato intervallo.
Rappresentazione JSON |
---|
{ "totalBudget": number, "startDateTime": { object ( |
Campi | |
---|---|
totalBudget |
Budget totale per l'intervallo specificato. È necessario specificare un budget totale se la priorità è Se il criterio |
startDateTime |
L'ora di inizio dell'applicazione di questo budget. Se non viene specificata un'ora di inizio, viene impostata come prima ora di inizio di tutti i turni specificati. |
endDateTime |
Ora di fine dell'applicazione di questo budget. Se non viene specificata un'ora di fine, viene impostata come ora di fine più recente di tutti i turni specificati. |
priority |
Livello di priorità per soddisfare i requisiti di budget durante il periodo di tempo specificato. La priorità predefinita è Tieni presente che se questa priorità è superiore ad altre priorità di vincolo e se |
ShiftAssignment
Un dipendente a cui è assegnato un ruolo di turno.
Rappresentazione JSON |
---|
{
"employeeId": string,
"shiftId": string,
"roleId": string,
"breaks": [
{
object ( |
Campi | |
---|---|
employeeId |
L'ID dipendente assegnato. |
shiftId |
ID turno assegnato al dipendente. |
roleId |
ID ruolo a cui è assegnato il dipendente per il turno. |
breaks[] |
Elenco delle interruzioni per questo compito. |
Pausa
Periodo di tempo in cui un dipendente interrompe il proprio lavoro durante un turno.
Rappresentazione JSON |
---|
{
"startDateTime": {
object ( |
Campi | |
---|---|
startDateTime |
L'ora di inizio di una pausa. |
durationMinutes |
Durata dell'interruzione in minuti. |
SolutionStatus
Stato della soluzione (ad esempio una pianificazione) fornito nella risposta di un risolutore.
Enum | |
---|---|
SOLUTION_STATUS_UNSPECIFIED |
Stato non specificato per la risposta. |
FEASIBLE |
La pianificazione restituita è fattibile, ma potrebbe non essere ottimale. |
OPTIMAL |
La pianificazione restituita è ottimale. |
INFEASIBLE |
Non esiste una pianificazione fattibile per i vincoli specificati. Il risolutore potrebbe restituire questo valore se non è possibile soddisfare un sottoinsieme dei vincoli con livello di priorità PRIORITY_MANDATORY . |
NOT_SOLVED |
Nessuna pianificazione trovata. |
NOT_SOLVED_DEADLINE_EXCEEDED |
Nessuna pianificazione trovata entro il limite di tempo specificato. |