Redistribute the routes of a schedule over teams and days with constraints
Source:R/calendar.R
schedule_calendar.Rdschedule_fieldwork() hands the routes of each base to its teams with a
simple rule (longest route first, one route per team-day). This function
solves that distribution exactly as a small integer programme, through
the highs package (in Suggests), which allows the constraints of real
field work: teams unavailable on some days, routes fixed to a team or a
day, routes that must precede others, a daily limit per team that lets
two short routes share one team-day. The objective finishes as early as
possible: it minimises the last working day of the schedule and, among
schedules with the same end, the sum of the days on which routes are
done.
Usage
schedule_calendar(
schedule,
availability = NULL,
fixed = NULL,
before = NULL,
daily_limit = NULL,
time_limit = 10
)Arguments
- schedule
A
fieldopt_schedulefromschedule_fieldwork().- availability
Optional data frame with columns
team,dayandavailable(logical): the team-days that are not listed are available. Team names are those of the calendar ("base-1","base-2", ...).- fixed
Optional data frame with columns
base,routeandteamand/orday: routes that must go to that team and/or that day.- before
Optional data frame with columns
base,route,base_afterandroute_after: the first route must be done on an earlier day than the second.- daily_limit
Maximum duration of a team-day (in the unit of the travel matrix); the routes already respect the
max_lengthof the schedule, so this is only useful to let several short routes share a day.NULLkeeps one route per team-day.- time_limit
Seconds allowed to the solver.
Value
The schedule with its calendar, summary and fits recomputed,
plus solver ("highs"), objective and status. An error when no
calendar satisfies the constraints within days.
Examples
set.seed(5)
pts <- data.frame(
unit = c("base1", "base2", paste0("s", 1:30)),
x = c(2, 8, runif(30, 0, 10)), y = c(2, 8, runif(30, 0, 10))
)
m <- travel_matrix(pts, method = "euclidean")
sch <- schedule_fieldwork(m,
units = paste0("s", 1:30), teams = c(base1 = 2, base2 = 1),
days = 5, max_stops = 4, iterations = 30
)
if (requireNamespace("highs", quietly = TRUE)) {
off <- data.frame(team = "base1-1", day = 1, available = FALSE)
schedule_calendar(sch, availability = off)
}
#>
#> ── Field schedule ──────────────────────────────────────────────────────────────
#> 30 units, 2 bases, 3 teams, 5 days available: the work fits.
#> "base1": 12 units, 2 teams, 3 routes, 2 of 5 days.
#> "base2": 18 units, 1 team, 5 routes, 5 of 5 days.