Multicommodity network flow model of a human resource allocation problem considering time periods
Reading time: 10 min.

Metadata

Ercsey, Zsolt; Kovács, Zoltán Multicommodity network flow model of a human resource allocation problem considering time periods. Cent. Eur. J. Oper. Res. 32, No. 4, 1041-1059 (2024).

Links: doi zbMATH

Authors:

Summary

Questions

Notes

Notation

Parameters and units of measure

Model 1

Inccorrect conditional constraint

Incorrect integer durations

Monotone sawtooth functions

Inflexible labour standards 4 formulation

Active Workers

Improved active workers

Objective

Typical cases

Misformatting

Section 3: multiple positions

Models

In ASCI-printable Symplex notation.

Model 1 as in paper

input NoL
input NoD
input NoP
input NoN[i in ...]
input P[i in ...] in ??? <min>
input NWH in ??? <min>
input XWH in ??? <min>
input RWH in ??? <min>
input delta

decision x[{1, ..., NoP}][{1, ..., NoL}] in {0, 1}
decision w[{0, ..., NoP}][{1, ..., NoL}] in {0, 1, ... }
decision h[{0, ..., NoP}][{1, ..., NoL}] in {0, 1, ... }
decision d[{0, ..., NoP}][{1, ..., NoL}] in {0, 1}
local P := sum[i in {1, ..., NoP}] P[i]

constraint EQ_1a[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  w[i][k] <= x[i][k] * M

constraint EQ_1b[k in {1, ..., NoL}] is
  w[0][k] = 0

constraint EQ_2[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  w[i][k] <= w[i - 1][k] + P[i]

constraint EQ_3[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  w[i][k] >= x[i - 1][k] + x[i][k] * P[i] + (x[i][k] - 1) * M

constraint EQ_4a[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  h[i][k] <= (1 - x[i][k]) * M

constraint EQ_4b[k in {1, ..., NoL}] is
  h[0][k] = 0

constraint EQ_5[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  h[i][k] <= h[i - 1][k] + P[i]

constraint EQ_6[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  h[i][k] >= x[i - 1][k] + (1 - x[i][k]) * P[i] + x[i][k] * M

constraint EQ_7a[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  d[i][k] <= x[i][k] + d[i - 1][k]

constraint EQ_7b[k in {1, ..., NoL}] is
  d[0][k] = 0

constraint EQ_8[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  d[i][k] => (x[i][k] + d[i - 1][k]) / 2

constraint EQ_9a[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  d[i][k] <= x[i][k] + d[i - 1][k]

constraint EQ_9b[k in {1, ..., NoL}] is
  d[0][k] = 0

constraint EQ_10[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  d[i][k] >= d[i-1][k]

constraint EQ_11[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  d[i][k] >= x[i][k]

constraint EQ_12a[i in {1, ..., NoP}] is
  sum[k in {1, ..., NoL}] x[i][k] >= NoN[i]

constraint EQ_12b[i in {1, ..., NoP}] is
  NoN[i] = 0 ===> sum[k in {1, ..., NoL}] x[i][k] = 0
  // Alternative: sum[k in {1, ..., NoL}] x[i][k] <= [NoN[i] = 0] * NoL

constraint EQ_13[k in {1, ..., NoL}][i in {1, ..., NoP}] is
  w[i][k] <= XWH

constraint EQ_14a[k in {1, ..., NoL}][i in {1, ..., NoP - 1}] is
  w[i][k] >= (x[i][k] - x[i + 1][k]) * NWH

constraint EQ_14b[k in {1, ..., NoL}] is
  w[NoP][k] >= x[NoP][k] * NWH

constraint EQ_15[k in {1, ..., NoL}][i in {1, ..., NoP - 1}] is
  h[i][k] >= (x[i + 1][k] - x[i][k]) * RWH + (d[i][k] - 1) * M

constraint EQ_16[k in {1, ..., NoL}] is
  sum[i in {1, ..., NoP}] x[i][k] * P[i] >= d[NoP][k] * (480 * NoD - delta)

constraint EQ_17[k in {1, ..., NoL}] is
  sum[i in {1, ..., NoP}] x[i][k] * P[i] <= d[NoP][k] * (480 * NoD + delta)

minimize sum[i in {1, ..., NoP - 1}][k in {1, ..., NoL}] x[i][k]

Model 1 rewritten

input NumWorkers in {1, 2, ...}
local Workers := {1, ..., NumWorkers}

input NumDays in {1, 2, ...}

input NumPeriods in {2, 3, ...}
local Periods := {1, 2, ..., NumPeriods}
local Instants := {0, 1, ..., NumPeriods}
local Switches := {1, 2, ..., NumPeriods - 1}

input Demand[p in Periods] in {0, ..., NumWorkers}

input Duration[p in Periods] in [0, infty[ <min>
local TotalDuration := sum[p in Periods] Duration[p]

input MinWork in [0, infty[ <min>
input MaxWork in [0, infty[ <min>
input MinRest in [0, infty[ <min>
input MaxDiff in [0, infty[ <min>

local StandardWork := 480 <min>

local RestPeriod[s in Switches] := max { p in Periods | p <= c, sum[q in {p, ..., c}] Duration[q] >= MinRest }
local RestPeriods[s in Switches] := {RestPeriod[s], ..., s} subseteq Switches

local Activity := {Work, Rest}
decision Time[Workers][Activity][Instants] in [0, infty[ <min>
decision Works[Workers][Periods] in {0, 1}
decision HasWorked[Workers] in {0, 1}
decision ShouldRest[Workers][Switches] in {0, 1}


local MaxWorkTime[p in Periods] := 
  min(MaxWork, sum[q in {1, ..., p} Duration[q])

constraint WorkTime_UB[w in Workers][p in Periods] is
  Time[w][Work][p] <= Works[w][p] * MaxWorkTime[p]

constraint WorkTime_Zero[w in Workers] is
  Time[w][Work][0] = 0

constraint WorkTime_Mon[w in Workers][p in Periods] is
  Time[w][Work][p] <= Time[w][Work][p - 1] + Duration[p]

constraint WorkTime_LB[w in Workers][p in Periods] is
  Time[w][Work][p] >= Works[w][p - 1] + Works[w][p] * Duration[p] + (Works[w][p] - 1) * MaxWorkTime[p]


local MaxRestTime[p in Periods] := 
  max(sum[q in {1, ..., p} Duration[q], sum[q in Periods] Duration[q] - StandardWork * NumDays + MaxDiff)

constraint RestTime_UB[w in Workers][p in Periods] is
  Time[w][Rest][p] <= (1 - Works[w][p]) * MaxRestTime[p]

constraint RestTime_Zero[w in Workers] is
  Time[w][Rest][0] = 0

constraint RestTime_Mon[w in Workers][p in Periods] is
  Time[w][Rest][p] <= Time[w][Rest][p - 1] + Duration[p]

constraint RestTime_LB[w in Workers][p in Periods] is
  Time[w][Rest][p] >= Works[w][Rest][p - 1] + (1 - Works[w][p]) * Duration[p] + Works[w][p] * MaxRestTime[p]


constraint ShouldRest_LB[w in Workers][s in Switches]][q in RestPeriods[s]] is 
  ShouldRest[w][s] >= Works[w][q]

constraint ShouldRest_UB[w in Workers][s in Switches] is 
  ShouldRest[w][s] <= sum[q in RestPeriods[s]] Works[w][q]


constraint HasWorked_LB[w in Workers][p in Periods] is
  HasWorked[w] >= Works[w][p]

constraint HasWorked_UB[w in Workers] is
  HasWorked[w] <=  sum[p in Periods] Works[w][p]


constraint EQ_12[p in Periods] is
  cases
    sum[w in Workers] Works[w][p] >= Demand[p] if Demand[p] > 0
    sum[w in Workers] Works[w][p] = 0 if Demand[p] = 0

constraint EQ_13[w in Workers][p in Periods] is
  Time[w][Work][p] <= MaxWork

constraint EQ_14_a[w in Workers][s in Switches] is
  Time[w][Work][p] >= (Works[w][s] - Works[w][s + 1]) * MinWork

constraint EQ_14_b[w in Workers] is
  Time[w][Work][NumPeriods] >= Works[w][NumPeriods] * MinWork

constraint EQ_15[w in Workers][s in Switches] is
  Time[w][Rest][s] >= (Works[w][s + 1] - Works[w][s] + ShouldRest[w][s] - 1) * MinRest
  with M := ???

constraint EQ_16[w in Workers] is
  sum[p in Periods] Works[w][p] * Duration[p] >= HasWorked[w] * (StandardWork * NumDays - MaxDiff)

constraint EQ_17[w in Workers] is
  sum[p in Periods] Works[w][p] * Duration[p] <= HasWorked[w] * (StandardWork * NumDays + MaxDiff)

minimize sum[p in Periods] Duration[p] sum[w in Workers] Works[w][p]