Risolve un problema di programmazione dei turni fisso a partire da SolveShiftSchedulingRequest
specificato assegnando i dipendenti a turni in modo che le preferenze di pianificazione sono ingrandite e le violazioni dei vincoli di pianificazione sono 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 |
ID problema o richiesta. |
solveParameters |
Parametri per controllare una singola soluzione del problema. |
employees[] |
Tutti i dipendenti disponibili da pianificare. |
shifts[] |
Tutti i turni formano il programma. |
coverageRequirements[] |
Requisiti di copertura per l'intero orizzonte di pianificazione. Queste norme specificano il numero di dipendenti che devono svolgere ciascun 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 presenti) per i requisiti di copertura non possono sovrapporsi per ogni località specifica. Il livello di priorità predefinito per ciascuno di questi vincoli è |
roleIds[] |
Elenco di tutti i ruoli possibili nella forza lavoro. Ogni dipendente deve avere almeno un ruolo che può essere assegnato per un turno. Un ruolo si riferisce a uno specifico incarico durante un turno (ad es. infermiere iscritto, dirigente chef, cameriere e così via). Quando un dipendente è assegnato a un turno, viene anche assegnato a un singolo ruolo specifico. |
skillIds[] |
Elenco di tutte le possibili competenze nella forza lavoro. Una competenza si riferisce a qualifiche aggiuntive che un dipendente può avere e che non riguardano un lavoro specifico assegnabile (ad esempio, certificazioni, lingue parlate e così via). Questo elenco può essere vuoto. Quando un dipendente viene assegnato a un turno, deve soddisfare tutte le competenze necessarie per quel turno. |
locationIds[] |
Elenco di tutte le posizioni possibili per l'insieme di turni nella programmazione. Questo elenco può essere vuoto. Specificare luoghi diversi può essere utile quando, ad esempio, un direttore infermieristico vuole pianificare molti infermieri in unità diverse dell'ospedale o, per un altro esempio, un direttore di hotel vuole programmare 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 soluzione) al problema di pianificazione. I suggerimenti per i compiti vengono ignorati se il compito è in contraddizione con un turno non assegnabile o una richiesta di pianificazione. |
Corpo della risposta
Risposta per l'API forza lavoro di pianificazione. Per ogni risposta, shiftAssignments
sarà vuoto se il valore solutionStatus
restituito è NOT_SOLVED_DEADLINE_EXCEEDED
o INFEASIBLE
. Se il valore solutionStatus
restituito è OPTIMAL
o FEASIBLE
, viene restituito un compito valido in shiftAssignments
. Per un'assegnazione di turni valida, vengono mantenute le seguenti proprietà:
- Ogni ID dipendente è contenuto nell'insieme di dipendenti indicato nella richiesta.
- Ogni ID ruolo assegnato al dipendente è contenuto nella serie di ID ruolo del dipendente specificato.
- Ogni ID variazione è contenuto nell'insieme di variazioni specificato 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 che si sovrappongono.
- Per la pianificazione specificata, non viene violata nessuna delle limitazioni 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 è FATTIBILE o OTTIMA, 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 fattibile o senza determinare se esiste una soluzione fattibile. Le richieste potrebbero non essere fattibili se i vincoli del livello di priorità OBBLIGATORIO non possono essere soddisfatti. |
shiftAssignments[] |
Elenco di tutti i compiti. Ogni |
statusMessage |
Se |
SolveParameters
Parametri che controllano una singola soluzione del problema di pianificazione dei turni.
Rappresentazione JSON |
---|
{ "timeLimit": string } |
Campi | |
---|---|
timeLimit |
Tempo massimo che il risolutore dovrebbe dedicare al problema. Se non viene configurato, il valore predefinito è 1 minuto. Questo valore non rappresenta un limite rigido e non tiene conto dell'overhead di comunicazione. La latenza prevista per risolvere il problema potrebbe superare leggermente questo valore. Durata in secondi con un massimo di nove cifre frazionarie e termina con " |
Dipendente
Un dipendente della forza lavoro da pianificare.
Rappresentazione JSON |
---|
{ "id": string, "roleIds": [ string ], "skillIds": [ string ], "shiftPreferences": [ { object ( |
Campi | |
---|---|
id |
ID univoco assegnato a questo dipendente. |
roleIds[] |
ID ruolo eseguibili da questo dipendente. Deve essere specificato almeno un ruolo. Quando un dipendente è assegnato a un turno, viene anche assegnato a un singolo ruolo di questo elenco. Al dipendente potrebbero essere assegnati ruoli diversi durante la finestra di pianificazione. |
skillIds[] |
ID delle competenze posseduti dal dipendente. Questo elenco può essere vuoto. Quando un dipendente è assegnato a un turno, utilizza qualsiasi sottoinsieme delle competenze elencate qui per coprire i requisiti di competenza per tutta la durata del turno assegnato. |
shiftPreferences[] |
Sposta 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 vincoli di pianificazione aggiuntivi non specificati in |
shiftRequests[] |
Elenco di richieste di turni per il dipendente. La richiesta può fare in modo che un dipendente venga assegnato o meno a turni specifici. Qualsiasi assegnazione di pianificazione fissa per il dipendente può essere rappresentata con un elemento |
hourlyContract |
Contratto che specifica le tariffe orarie regolari e di straordinario del dipendente. |
ShiftPreference
Una preferenza numerica per un determinato ID variazione.
Rappresentazione JSON |
---|
{ "shiftId": string, "preference": integer } |
Campi | |
---|---|
shiftId |
ID spostamento per il quale è specificata la preferenza. |
preference |
Valori di preferenza più alti indicano un cambiamento più desiderabile. |
SchedulingConstraint
Vincolo di pianificazione specifico per un determinato dipendente. Il vincolo specificato viene applicato solo durante l'intervallo [startDateTime,
endDateTime)
specificato.
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 in cui viene applicato questo vincolo di pianificazione (inclusa). |
endDateTime |
L'ora di fine in cui viene applicato questo vincolo di pianificazione (esclusa). |
Campo unione type . Il tipo di vincolo specificato. Ogni vincolo viene applicato solo entro l'intervallo di tempo specificato sopra. type può essere solo uno dei seguenti: |
|
minimumMinutes |
Numero minimo di minuti in cui il dipendente può lavorare. Se al dipendente è assegnato un turno che si sovrappone (totalmente o parzialmente) all'intervallo di tempo, il numero di minuti in cui il turno si sovrappone alla finestra temporale è incluso in questo conteggio. |
maximumMinutes |
Numero massimo di minuti in cui il dipendente può lavorare nella finestra temporale. Se al dipendente è assegnato un turno che si sovrappone (totalmente o parzialmente) all'intervallo di tempo, il numero di minuti in cui il turno si sovrappone alla finestra temporale è incluso in questo conteggio. |
minimumConsecutiveWorkDays |
Numero minimo di giorni consecutivi in cui il dipendente può lavorare. Un dipendente lavora in un giorno specifico se è assegnato a un turno che inizia durante quella giornata. Nel conteggio è incluso qualsiasi turno assegnato al dipendente che inizia nella finestra temporale. |
maximumConsecutiveWorkDays |
Numero massimo di giorni consecutivi in cui il dipendente può lavorare. Un dipendente lavora in un giorno specifico se è assegnato a un turno che inizia durante quella giornata. Nel conteggio è incluso qualsiasi turno assegnato al dipendente che inizia nella finestra temporale. |
minimumShiftCount |
Numero minimo di turni che il dipendente può lavorare. Nel conteggio viene incluso qualsiasi turno assegnato al dipendente che si sovrappone completamente alla finestra temporale. |
maximumShiftCount |
Numero massimo di turni che il dipendente può lavorare. Nel conteggio viene incluso qualsiasi turno assegnato al dipendente che si sovrappone completamente alla finestra temporale. |
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 adattamenti completamente inclusi in [ |
Priorità
Il livello di priorità per qualsiasi vincolo nella pianificazione di un dipendente o nei requisiti di copertura. Sono inclusi SchedulingConstraint
, ResourceConstraint
, ShiftRequest
e CoverageRequirement
. Poiché potrebbero esserci vincoli in conflitto, non è sempre possibile soddisfare tutti i vincoli. Di conseguenza, ogni tipo di vincolo ha una priorità (dall'utente o predefinita) che informa il risolutore dell'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. Sono i primi a essere presi in considerazione per violazione se non è possibile trovare una soluzione fattibile. |
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 è possibile trovare una soluzione fattibile dopo aver allentato tutti i vincoli con priorità PRIORITY_LOW , i vincoli con priorità PRIORITY_MEDIUM vengono considerati i successivi 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 a essere considerati 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. Si tratta di una versione astratta dello standard SchedulingConstraint
più specifico e più flessibile per l'utente. Questo messaggio consente di specificare molti vincoli di pianificazione che non possono essere specificati in SchedulingConstraint.type
.
Rappresentazione JSON |
---|
{
"priority": enum ( |
Campi | |
---|---|
priority |
Livello di priorità di questo vincolo della risorsa. La priorità predefinita per tutti i vincoli delle risorse è |
resourceUsages |
Quantità di risorse utilizzata dai turni. Ad esempio, se questo vincolo si applica alle ore minime e massime lavorate da un dipendente in una determinata settimana, 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 delle risorse. |
maximumResourceUsage |
Utilizzo massimo delle risorse per soddisfare un vincolo delle risorse. |
ShiftRequest
La richiesta di un dipendente di essere assegnata o meno 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 delle variazioni della richiesta di pianificazione. |
type |
Tipo di richiesta, ad esempio se la richiesta è assegnata o meno all'insieme di turni. |
WorkStatus
Che un dipendente lavori o meno.
Enum | |
---|---|
WORK_STATUS_UNSPECIFIED |
Stato del lavoro sconosciuto. |
STATUS_WORK |
Stato che rappresenta un dipendente che lavora. |
STATUS_NOT_WORK |
Stato che rappresenta un dipendente non lavorativo. |
HourlyContract
Specifica una tariffa oraria di base, differenziali di tariffa e moltiplicatori di straordinari per determinare la retribuzione per un dipendente. Tieni presente che le normative vigenti in luoghi diversi potrebbero richiedere un calcolo diverso dell'indennità per gli straordinari. Il risolutore approssima la retribuzione degli straordinari per ridurre al minimo un'approssimazione del costo totale o soddisfare un budget (vedi BudgetRequirement
). Non è inteso come uno strumento per calcolare le buste paga.
Rappresentazione JSON |
---|
{
"baseHourlyRate": number,
"hourlyRateShiftDifferentials": {
string: number,
...
},
"overtimePeriods": [
{
object ( |
Campi | |
---|---|
baseHourlyRate |
Il compenso per il lavoro di un'ora non straordinaria. Se al dipendente si applicano più tariffe, vengono applicate differenze di tariffa rispetto a questa tariffa oraria di base. Inoltre, se sono presenti più tariffe, la tariffa oraria di base deve essere quella minima tra queste. |
hourlyRateShiftDifferentials |
Il differenziale della tariffa oraria, pagato in aggiunta al 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 (in genere 168 ore o sette periodi consecutivi di 24 ore) utilizzato per determinare l'importo della compensazione per gli straordinari. Ogni periodo ha un moltiplicatore degli straordinari (ad es. 1.5) rispetto al baseHourlyRate
e a un limite al numero di ore considerate lavorative regolari (non straordinari). Qualsiasi turno che si sovrappone alla finestra di tempo startDateTime
(incluso) e endDateTime
(escluso) viene conteggiato nel numero totale di ore lavorate nel periodo. Se la sovrapposizione è parziale, vengono conteggiate solo le ore che si sovrappongono.
Rappresentazione JSON |
---|
{ "overtimeMultiplier": number, "startDateTime": { object ( |
Campi | |
---|---|
overtimeMultiplier |
Moltiplicatore per calcolare la tariffa oraria straordinaria (deve essere maggiore o uguale a 1,0). In genere, la tariffa oraria relativa agli straordinari viene calcolata come |
startDateTime |
Ora di inizio del periodo di tempo straordinario. Se un turno si sovrappone in questo orario, le ore di questo spostamento vengono conteggiate a partire da |
endDateTime |
Ora di fine del periodo di tempo straordinario. Se un turno si sovrappone a questo orario, le ore di questo turno vengono conteggiate fino a |
maximumRegularHours |
Numero massimo di ore di lavoro pagate con una tariffa regolare (non straordinario). 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 spostamento. |
locationId |
ID località in cui è stato applicato questo turno. Può essere vuoto. |
startDateTime |
L'ora di inizio del turno (inclusa). |
endDateTime |
L'ora di fine del turno (esclusa). Attualmente, il risolutore ammette solo turni di durata inferiore a 24 ore. |
breakRules[] |
Un elenco di regole di interruzione che si verificano durante il turno. Ai dipendenti che svolgono questo turno viene assegnata una pausa ogni |
BreakRule
Una regola che determina quando può iniziare una pausa all'interno di un turno e la sua durata. L'elenco di tutte le possibili interruzioni prese in considerazione viene 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, le interruzioni considerate sono: [10:00, 10:30], [10:20, 10:50], [10:40, 11:1].
Rappresentazione JSON |
---|
{ "earliestStartTime": { object ( |
Campi | |
---|---|
earliestStartTime |
La prima ora di inizio della pausa (inclusa). È possibile impostare solo |
latestStartTime |
L'ultima ora di inizio della pausa (inclusa). È possibile impostare solo |
durationMinutes |
Durata dell'interruzione in minuti. |
ruleIncrementMinutes |
[Facoltativo] Incremento del tempo in minuti per tutte le interruzioni che possono essere considerate in questa regola per le interruzioni. Se non viene configurato, il valore predefinito è |
CoverageRequirement
Un requisito di copertura specifica il numero di dipendenti necessari per un insieme di ruoli e/o competenze durante una particolare finestra temporale e in una determinata località. Gli intervalli DateTime in una determinata località non possono sovrapporsi. In alternativa, è possibile fornire un elenco di ID turni al posto di una finestra temporale e di una località. Solo i dipendenti che possono essere assegnati a un ruolo specifico (o che possiedono una competenza specifica) possono soddisfare questo requisito.
Per un determinato ruolo e/o competenza, il requisito di copertura viene soddisfatto quando almeno targetEmployeeCount
di dipendenti lavora in ogni momento della finestra temporale (o per ogni turno nel seguente paese: shiftIds
). Al contrario, il requisito di copertura viene violato se in qualsiasi momento della finestra temporale (o per uno qualsiasi dei turni in shiftIds
) ci sono meno di targetEmployeeCount
dipendenti che lavorano durante la finestra temporale. Un numero maggiore di dipendenti che lavorano rispetto a targetEmployeeCount
soddisfa comunque il requisito, ma il risolutore riduce al minimo l'impiego eccessivo di personale.
Rappresentazione JSON |
---|
{ "startDateTime": { object ( |
Campi | |
---|---|
startDateTime |
L'ora di inizio del requisito di copertura (incluso). 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. Il campo |
shiftIds[] |
Se impostato, i requisiti di ruolo e competenza 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 l'intervallo di tempo. È necessario specificare al massimo un |
skillRequirements[] |
Numero richiesto di dipendenti con le competenze specificate assegnate ai turni durante l'intervallo di tempo. È necessario specificare al massimo un |
RoleRequirement
Numero obbligatorio di dipendenti da assegnare al ruolo specificato durante l'intervallo 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 la finestra temporale. |
priority |
Livello di priorità per questo vincolo di requisito. La priorità predefinita per tutti i vincoli delle risorse è |
SkillRequirement
Numero richiesto di dipendenti che lavorano nell'intervallo di tempo e possiedono la competenza specificata.
Rappresentazione JSON |
---|
{
"skillId": string,
"targetEmployeeCount": integer,
"priority": enum ( |
Campi | |
---|---|
skillId |
ID competenza per il requisito. |
targetEmployeeCount |
Numero desiderato di dipendenti con le competenze specifiche che lavorano nell'intervallo di tempo. |
priority |
Livello di priorità per questo vincolo di 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 |
Ora di inizio durante il quale si applica il budget. Se l'ora di inizio non è specificata, viene impostata come la prima ora di inizio di tutti i turni specificati. |
endDateTime |
Ora di fine per l'applicazione del budget. Se l'ora di fine non è specificata, viene impostata come l'ultima ora di fine di tutti i turni. |
priority |
Livello di priorità per soddisfare il requisito di budget durante l'intervallo 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 assegnare il ruolo di turno.
Rappresentazione JSON |
---|
{
"employeeId": string,
"shiftId": string,
"roleId": string,
"breaks": [
{
object ( |
Campi | |
---|---|
employeeId |
L'ID dipendente assegnato. |
shiftId |
ID spostamento assegnato al dipendente. |
roleId |
ID ruolo a cui è assegnato il dipendente per il turno. |
breaks[] |
Elenco delle pause per questo compito di turno. |
Pausa
Un 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 (ovvero 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 alcuna 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. |