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]) argv_index = day_index + 2 # number of days is fixed at 7 so the number of shifts will be in index 8 num_shifts = sys.argv[argv_index] hour_shifts = [] for shift_ctr in range(0, int(num_shifts)): # form list within the list hour_shift_item = [] shift = sys.argv[argv_index+1] # append to list hour_shift_item.append(shift) # append the list to the list hour_shifts.append(hour_shift_item) argv_index+=1 # 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()