0

I'm new to ORTools and trying to implement an algo for employee scheduling problem involving multiple shifts and work centers over month using ORTools,

https://notebook.community/google/or-tools/examples/notebook/sat/schedule_requests_sat,
https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py,

etc.... For a given work center, the demand for employees during a given shift is required (for ex.: 3 employees on am shift, 2 employees on pm shift and 1 employee on evening shift. The objective is to assign the selected employees to shifts and work centers. i did something like this below for 40 employees, 10 work centers and month but the solution ends with some employees with 42 hours and others with like 7 hours....

            shift = {}
            for n in all_nurses:
                for s in all_shifts:  # range(num_shifts):
                    for d in all_days:
                        for l in all_sites:
                            shift[(n, s, d, l)] = model.NewBoolVar(
                                'shift_n%is%id%il%i' % (n, s, d, l))

Each nurse works at most one shift per day.

            for n in all_nurses:
                for d in all_days:
                    model.Add(sum(shift[(n, s, d, l)]
                                  for s in range(num_shifts) for l in all_sites) <= 1)

Each nurse works 5 days week

            for n in all_nurses:
                week = []
                for l in all_sites:
                    for s in all_shifts:
                        for d in all_days:
                            week.append(shift[(n, s, d, l)])
                        # week.append(sum(shifts[(n,d,s)] for s in all_shifts))
                # print(week)
            model.Add(sum(week) == 5)

the numbers of nurses on day d in shift s at site l should be less or equal to weekly_cover_demands[l][d][s]

      for l in all_sites:
                for d in all_days:
                    for s in range(num_shifts):
                        model.Add(sum(shift[(n, s, d, l)]
                                      for n in all_nurses) <= weekly_cover_demands[l][d][s])
            model.Maximize(
                sum(shift[(n, s, d, l)]
                    for l in all_sites for d in all_days for n in all_nurses for s in range(num_shifts)))
10 Rep
  • 2,217
  • 7
  • 19
  • 33

1 Answers1

0

There are some problems in your source code.

  1. You want the algorithm to run weekly, but you provided a monthly input as an input. You should either run weekly or add the week numbers.

a) You can change end date with 7 days

dates = {'start': '2021-02-01T00:00:00.000Z',
         'end': '2021-02-08T00:00:00.000Z'}

b) Or you can use week numbers. This option can be more difficult.

all_weeks = range(4)
all_days = range(7)
for n in all_agents:
    for s in all_shifts:
        for w in all_weeks:
            for d in all_days:
                for l in all_sites:
                  ...
  1. model.Add(sum(week) <= 5) line missing tab space.
for n in all_agents:
    week = []
    for d in all_days:
        for l in all_sites:
            for s in all_shifts:
                week.append(shift[(n, s, d, l)])
    model.Add(sum(week) <= 5)
  1. Day range set for only in 7 days, other 21 days there are no constraints. You should add week number iteration described in 2. problem. Or consider the problem as only weekly.
for l in all_sites:
    for d in range(7):
        for s in range(num_shifts):
            model.Add(sum(shift[(n, s, d, l)]
                          for n in all_agents) == weekly_cover_demands[l, d, s])
  1. I recommend to write outputs method as below. Append method increases file size after every run. In each iteration, file is opening again and again, it is not convenient.
with open('___output.txt', 'w') as f:
    for l in all_sites:
        for d in all_days:
            for s in all_shifts:
                for n in all_agents:
                    if solver.Value(shift[(n, s, d, l)]) == 1:
                        print("nurse {} covers shift {} on day {}  at site {}".format(
                            agents[n], s, startschedule + datetime.timedelta(days=d), l), file=f)

Conclusion, the ortools can not find any feasible solution. Please check your constraints or input parameters. I think you should keep the algorithm is simple and think weekly instead of monthly.

Ismail Durmaz
  • 2,521
  • 1
  • 6
  • 19