from __future__ import print_function from ortools.linear_solver import pywraplp import sys def main(): # days days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] # hours hours = [ '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'] # initialize required hours - req_hours[days][hours] req_hours = [[0 for x in range(len(hours))] for y in range(len(days))] # get arguments # there will be 8 arguments, monday to sunday schedule and the shift selected # sample argument: # 0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0 0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0 0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0 0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0 0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0 0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0 0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0 24_7 for day_index in range(0, len(days)): hours_string = sys.argv[day_index + 1] hours_data = hours_string.split('-') for hour_index in range(0, len(hours)): req_hours[day_index][hour_index] = int(hours_data[hour_index]) # index of shift selected is 8 shift = sys.argv[8] hour_shifts = [] if shift == "24_7": hour_shifts = [ ['00 - 09', 0, 1, 2, 3, 4, 5, 6, 7, 8], ['01 - 10', 1, 2, 3, 4, 5, 6, 7, 8, 9], ['02 - 11', 2, 3, 4, 5, 6, 7, 8, 9, 10], ['03 - 12', 3, 4, 5, 6, 7, 8, 9, 10, 11], ['04 - 13', 4, 5, 6, 7, 8, 9, 10, 11, 12], ['05 - 14', 5, 6, 7, 8, 9, 10, 11, 12, 13], ['06 - 15', 6, 7, 8, 9, 10, 11, 12, 13, 14], ['07 - 16', 7, 8, 9, 10, 11, 12, 13, 14, 15], ['08 - 17', 8, 9, 10, 11, 12, 13, 14, 15, 16], ['09 - 18', 9, 10, 11, 12, 13, 14, 15, 16, 17], ['10 - 19', 10, 11, 12, 13, 14, 15, 16, 17, 18], ['11 - 20', 11, 12, 13, 14, 15, 16, 17, 18, 19], ['12 - 21', 12, 13, 14, 15, 16, 17, 18, 19, 20], ['13 - 22', 13, 14, 15, 16, 17, 18, 19, 20, 21], ['14 - 23', 14, 15, 16, 17, 18, 19, 20, 21, 22], ['15 - 00', 15, 16, 17, 18, 19, 20, 21, 22, 23], ['16 - 01', 16, 17, 18, 19, 20, 21, 22, 23, 0], ['17 - 02', 17, 18, 19, 20, 21, 22, 23, 0, 1], ['18 - 03', 18, 19, 20, 21, 22, 23, 0, 1, 2], ['19 - 04', 19, 20, 21, 22, 23, 0, 1, 2, 3], ['20 - 05', 20, 21, 22, 23, 0, 1, 2, 3, 4], ['21 - 06', 21, 22, 23, 0, 1, 2, 3, 4, 5], ['22 - 07', 22, 23, 0, 1, 2, 3, 4, 5, 6], ['23 - 08', 23, 0, 1, 2, 3, 4, 5, 6, 7]] if shift == "8AM_5PM": hour_shifts = [ ['07 - 16', 7, 8, 9, 10, 11, 12, 13, 14, 15], ['08 - 17', 8, 9, 10, 11, 12, 13, 14, 15, 16]] if shift == "7AM_10PM": hour_shifts = [ ['07 - 16', 7, 8, 9, 10, 11, 12, 13, 14, 15], ['08 - 17', 8, 9, 10, 11, 12, 13, 14, 15, 16], ['09 - 18', 9, 10, 11, 12, 13, 14, 15, 16, 17], ['10 - 19', 10, 11, 12, 13, 14, 15, 16, 17, 18], ['11 - 20', 11, 12, 13, 14, 15, 16, 17, 18, 19], ['12 - 21', 12, 13, 14, 15, 16, 17, 18, 19, 20], ['13 - 22', 13, 14, 15, 16, 17, 18, 19, 20, 21]] # all possible days riders come in day_shifts = [ ['Mon - Sat', 0, 1, 2, 3, 4, 5], # Mon - Sat ['Tue - Sun', 1, 2, 3, 4, 5, 6], # Tue - Sun ['Wed - Mon', 2, 3, 4, 5, 6, 0], # Wed - Mon ['Thu - Tue', 3, 4, 5, 6, 0, 1], # Thu - Tue ['Fri - Wed', 4, 5, 6, 0, 1, 2], # Fri - Wed ['Sat - Thu', 5, 6, 0, 1, 2, 3], # Sat - Thu ['Sun - Fri', 6, 0, 1, 2, 3, 4]] # Sun - Fri # build shift lookup index # instantiate glop solver solver = pywraplp.Solver('SolveSchedule', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING) # solver variables solv_shifts = [[0 for x in range(len(hour_shifts))] for y in range(len(day_shifts))] # objective objective = solver.Objective() # variables for shifts for day_index in range(0, len(day_shifts)): for hour_index in range(0, len(hour_shifts)): solv_shifts[day_index][hour_index] = solver.IntVar(0, solver.infinity(), day_shifts[day_index][0] + ' ' + hour_shifts[hour_index][0]) # objective is to minimize number of shifts objective.SetCoefficient(solv_shifts[day_index][hour_index], 1) objective.SetMinimization() # set constraints constraints = [[0 for x in range(len(hours))] for y in range(len(days))] # go through all days for day_index in range(0, len(days)): # go through all hours for hour_index in range(0, len(hours)): # hour personnel should be equal or less than shift personnel that covers those hours # set the required manpower for that day + hour combo # print('setting constraint for', day_index, '-', hour_index, '=', req_hours[day_index][hour_index]) constraints[day_index][hour_index] = solver.Constraint(req_hours[day_index][hour_index], solver.infinity()) # go through all day shifts for shift_day in range(0, len(day_shifts)): # go through days inside day shift for shift_day_index in range(1, len(day_shifts[shift_day])): # is day shift part of that day? if day_index == day_shifts[shift_day][shift_day_index]: # go through all hour shifts for shift_hour in range(0, len(hour_shifts)): # go through all hours inside hour shift for shift_hour_index in range(1, len(hour_shifts[shift_hour])): # is hour shift part of the hour if hour_index == hour_shifts[shift_hour][shift_hour_index]: # print(day_index, ' - ', hour_index, ' vs ', day_shifts[shift_day][shift_day_index], ' - ', hour_shifts[shift_hour][shift_hour_index]) # add it to constraint constraints[day_index][hour_index].SetCoefficient(solv_shifts[shift_day][shift_hour], 1) # solve it! status = solver.Solve() #print('Number of variables =', solver.NumVariables()) #print('Number of constraints =', solver.NumConstraints()) if status == solver.OPTIMAL: #print('Optimal solution found!') for day_index in range(0, len(day_shifts)): for hour_index in range(0, len(hour_shifts)): result = solv_shifts[day_index][hour_index].solution_value() if result > 0: print(day_index, hour_index, int(solv_shifts[day_index][hour_index].solution_value()), sep='-') #print(day_shifts[day_index][0], ' ', hour_shifts[hour_index][0], ' = ', int(solv_shifts[day_index][hour_index].solution_value()), sep='') else: if status == solver.FEASIBLE: print('Feasible solution found!') else: print('Could not solve problem.') if __name__ == '__main__': main()