def simulated_annealing(self, time_table, iterations=100000): """ This method will do simulated_annealing to try find a better, or hopefully optimal solution. It will randomly swap two slots. """ def sigmoid(gamma): if gamma < 0: return 1 - 1 / (1 + math.exp(gamma)) return 1 / (1 + math.exp(-gamma)) days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] initial = timetable.Timetable(3) for day_slots in time_table.schedule.items(): for slot, value in day_slots[1].items(): initial.schedule[day_slots[0]][slot] = time_table.schedule[ day_slots[0]][slot] best_time_table = timetable.Timetable(3) time_table.scheduleChecker(self.tutorList, self.moduleList) lowest_cost = time_table.cost for k in range(1, iterations): T = iterations / k + 1 if T == 0: break # randomly swap two slots day1 = days[random.randint(0, 4)] day2 = days[random.randint(0, 4)] slot1 = random.randint(1, 10) slot2 = random.randint(1, 10) module1 = time_table.getSession(day1, slot1) module2 = time_table.getSession(day2, slot2) time_table.addSession(day1, slot1, module2[0], module2[1], module2[2]) time_table.addSession(day2, slot2, module1[0], module1[1], module1[2]) if time_table.scheduleChecker(self.tutorList, self.moduleList): if time_table.cost < lowest_cost: lowest_cost = time_table.cost for day_slots in time_table.schedule.items(): for slot, value in day_slots[1].items(): best_time_table.schedule[day_slots[0]][ slot] = time_table.schedule[day_slots[0]][slot] elif sigmoid( (time_table.cost - lowest_cost) / T) < random.random(): time_table.addSession(day1, slot1, module1[0], module1[1], module1[2]) time_table.addSession(day2, slot2, module2[0], module2[1], module2[2]) if best_time_table.scheduleChecker(self.tutorList, self.moduleList): return best_time_table initial.scheduleChecker(self.tutorList, self.moduleList) return initial
def arrange_timetable(self, subject, arg_timetable): for num in range(len(subject)): # 学年・クラス算出 a = subject[num].subcode / 100 grade = int(a / 10) cla = int(a % 10) # 選択を飛ばす if (grade == 8): continue while (True): # 乱数 rand = random.randint(1, DAY * (TIME - 1) - 1) # 曜日・時間算出 day = rand % DAY time = int(rand / DAY) # 固定授業のみ if (hasattr(arg_timetable[grade][cla][day][time], "fix_flag")): pass else: break # 引数 args = { "subname": subject[num].subname, "subcode": subject[num].subcode, "teachernum": subject[num].teachernum, "teachercode": subject[num].teachercode } arg_timetable[grade][cla][day][time] = timetable.Timetable(**args)
def __init__(self, sys_path: str = "", time_delta_hour: int = 3, base_name: str = "Default"): # инициализация времени и часового пояса self.time_delta_hour = time_delta_hour self.time_delta = datetime.timedelta(hours=self.time_delta_hour, minutes=0) # инициализация системной папки self.sys_path = sys_path # виды полей для ответа self.ANS_PEER_ID = "peer_id" self.ANS_MESSAGE = "message" self.AMS_RAND_ID = "random_id" self.ANS_KEYBOARD = "keyboard" self.ANS_ATTACHMENT = "attachment" # виды клавиатур self.KBRD_MENU = "menu" self.KBRD_TIMETABLE = "timetable" self.KBRD_ACC_PLAN = "academic_plan" self.KBRD_SETTINGS = "settings" self.KBRD_MORNING_M = "morning_mailing" self.KBRD_EVENING_M = "evening_mailing" self.KBRD_EMPTY = "empty" # модуль расписания self.timetale = timetable.Timetable(self.sys_path, self.time_delta_hour) # модуль клавиатур self.keyboards = keyboard.KeyBoard() # инициализация клавиатур self._init_keyboards() # база данных self.base_name = base_name self.database = database.DataBase(sys_path, self.base_name)
def solve_timetable_test(file_name): rw = ReaderWriter.ReaderWriter() tutors, modules = rw.readRequirements(file_name) time_table = timetable.Timetable(1) module_tutor_pairs = generate_module_tutor_pairs(time_table, modules, tutors) can_solve_slot(time_table, module_tutor_pairs, 1) print(file_name + ': ' + str(time_table.task1Checker(tutors, modules)))
def set_(self, grad, arg_timetable): for num in range(len(grad)): # 学年・クラス算出 a = grad[num].subcode / 100 grade = int(a / 10) cla = int(a % 10) # 専攻科2年は水~金 if (grade == 7): start = 2 else: start = 3 # 時間割配置 for day in range(start, 5): for time in range(3 - grad[num].cont, 4): # 引数 args = { "subname": grad[num].subname, "subcode": grad[num].subcode, "fix_flag": False } arg_timetable[grade][cla][day][time] = timetable.Timetable( **args)
def load(self, map_directory, tiles): self.chrono_config = omsi_files.OmsiFile(map_path=map_directory, pattern=os.path.join( self.chrono_directory, "Chrono.cfg")) for f in [ os.path.relpath(x, map_directory) for x in glob.glob( os.path.join(map_directory, self.chrono_directory, "Chrono_*.dsc")) ]: self.chrono_translations.add( omsi_files.OmsiFile(map_path=map_directory, pattern=f, optional=True)) for tile in tiles: if os.path.isfile( os.path.join(map_directory, self.chrono_directory, tile.map_file)): print("Parsing chrono tile file " + os.path.join( map_directory, self.chrono_directory, tile.map_file)) self.chrono_tiles_infos.append( ChronoTileInfo(directory=self.chrono_directory, pos_x=tile.pos_x, pos_y=tile.pos_y, tile=_chrono_tile_parser.parse( os.path.join(map_directory, self.chrono_directory, tile.map_file)))) self.timetable = timetable.Timetable(self.chrono_directory) self.timetable.load(map_directory)
def getSortedDemoList(self): tt = timetable.Timetable(2) demos = [] sortedDemos = [] # Iterate over demographics and work out how many comics can do the test/main show for the given topics for demographic in self.demographic_List: canDoMainCount = 0 # Check how many comics are qualified to do the main show for this demo for comedian in self.comedian_List: if tt.canMarket(comedian, demographic, False): canDoMainCount += 1 demos.append([demographic, False, canDoMainCount]) canDoTestCount = 0 # Check how many comics are qualified to do the test show for this demo for comedian in self.comedian_List: if tt.canMarket(comedian, demographic, True): canDoTestCount += 1 demos.append([demographic, True, canDoTestCount]) # Sort list by the number of comics that can do show sortedDemos = sorted(demos, key=lambda p: p[2]) return sortedDemos
def set_(self, specsub, choicesub, arg_timetable): # 初期化 count_choice = [-1 for i in range(GRADE + 1)] for num in range(len(choicesub)): # 先生 teacher = [] teachernum = 0 # 学年・日付・時間計算 grade = int(choicesub[num].subcode / 1000) count_choice[grade] += 1 day = CHOICE[grade][count_choice[grade]] % DAY time = int(CHOICE[grade][count_choice[grade]] / DAY) for i in range(len(specsub)): for j in range(choicesub[num].choicenum): if (specsub[i].subcode == choicesub[num].choicecode[j]): for k in range(specsub[i].teachernum): teacher.append(specsub[i].teachercode[k]) teachernum += 1 for cla in range(1, CLASS + 1): # 引数 args = { "subname": choicesub[num].subname, "subcode": choicesub[num].subcode, "teachernum": teachernum, "teachercode": teacher, "simunum": choicesub[num].choicenum, "simucode": choicesub[num].choicecode, "fix_flag": False } arg_timetable[grade][cla][day][time] = timetable.Timetable( **args)
def to_timetable(self): time_table = timetable.Timetable(self.TASK_NUM) slot = 0 for day, tutor, typ, module in self.scheduled.tuples(): slot = (slot % self.SLOT_COUNT) + 1 time_table.addSession(day, slot, tutor, module, typ) return time_table
def solve_timetable(): rw = ReaderWriter.ReaderWriter() tutors, modules = rw.readRequirements("ExampleProblems2/Problem20.txt") time_table = timetable.Timetable(1) module_tutor_pairs = generate_module_tutor_pairs(time_table, modules, tutors) # attempt to solve the task can_solve_slot(time_table, module_tutor_pairs, 1) print_timetable(time_table, tutors, modules)
def get(self, serv, Event): event = Event if self.modes(event) not in [1] and self.mode != 1: if event.object.message['text'] == "Начать": self.ret['message'] = 'Привет!' self.ret["random_id"] = 0 self.ret["peer_id"] = event.object.message['peer_id'] self.ret["keyboard"] = self.get_buttons('start') return self.ret if event.object.message['text'] == "Расписание": self.ret['message'] = timetable.Timetable() self.ret["random_id"] = 0 self.ret["peer_id"] = event.object.message['peer_id'] self.ret["keyboard"] = self.get_buttons('start') return self.ret elif event.object.message['text'] == 'Погода': user_id = event.object.message['peer_id'] city = serv.get_user_city(user_id) self.ret['message'] = Weather.get_weather_today(city) self.ret["random_id"] = 0 self.ret["peer_id"] = event.object.message['peer_id'] self.ret["keyboard"] = self.get_buttons('start') return self.ret else: self.ret['message'] = "Команда не распознана" self.ret["random_id"] = 0 self.ret["peer_id"] = event.object.message['peer_id'] self.ret["keyboard"] = self.get_buttons('start') return self.ret elif self.mode != 1 and self.modes(event) == 1: self.ret['message'] = "Введите неправильный глагол" self.ret["random_id"] = 0 self.ret["peer_id"] = event.object.message['peer_id'] self.ret["keyboard"] = self.get_buttons('go_back') self.mode = self.modes(event) return self.ret elif self.mode == 1: if self.modes(event) == 0: self.ret['message'] = "Возврат в главное меню" self.ret["random_id"] = 0 self.ret["peer_id"] = event.object.message['peer_id'] self.ret["keyboard"] = self.get_buttons('start') self.mode = self.modes(event) return self.ret else: self.ret['message'] = irregular_V.get_verb( event.object.message['text']) self.ret["random_id"] = 0 self.ret["peer_id"] = event.object.message['peer_id'] self.ret["keyboard"] = self.get_buttons('go_back') return self.ret
def schedule_to_timetable(self, schedule): time_table = timetable.Timetable(self.TASK_NUM) slot = 0 # for day, tutor, typ, module in self.scheduled.tuples(): for day, allocation in schedule.items(): for module, typ, tutor in allocation: slot = (slot % self.SLOT_COUNT) + 1 time_table.addSession(day, slot, tutor, module, typ) return time_table
def createSchedule(self): #Do not change this line timetableObj = timetable.Timetable(1) module_tutor_pairs = self.task_1_generate_module_tutor_pairs( timetableObj) self.task_1_can_solve_slot(timetableObj, module_tutor_pairs, 1) #Do not change this line return timetableObj
def createLabSchedule(self): #Do not change this line timetableObj = timetable.Timetable(2) #Here is where you schedule your timetable #This line generates a random timetable, that may not be valid. You can use this or delete it. self.randomModAndLabSchedule(timetableObj) #Do not change this line return timetableObj
def createMinCostSchedule(self): timetableObj = timetable.Timetable(3) print("Calculating the minimum cost...") print("Can take longer for problems 6 and 8") solutions = list() takenTutors = dict() loopcount = 0 loop = True # create loop to repeat backtracking until minimum value solution is found while loop: assignment = list() # stores the successful assignments slots = list() solutionCost = 0 # stores solution cost of this backtrack call # sets all tutors as available for tutor in self.tutorList: takenTutors[tutor] = 0 # create empty schedule without anything assigned self.emptySchedule(timetableObj) # calls backtrack method self.backtrack3(timetableObj,assignment,slots,solutionCost,solutions,takenTutors) # if optimal solution is reached if solutions[loopcount][1] <= 10050: loop = False loopcount += 1 # timeout for cases when optimal solution is not 10050 if loopcount > 200: loop = False # sort the solutions by the cost sortedSolutions = sorted(solutions,key = lambda x: x[1]) # minimum cost is at first index finalAssignment = sortedSolutions[0][0] # add lowest cost assignment to timetable object for x in range(len(finalAssignment)): t = finalAssignment[x][0] m = finalAssignment[x][1] d = finalAssignment[x][2] s = finalAssignment[x][3] ty = finalAssignment[x][4] if ty == "module": timetableObj.addSession(d, s, t, m, "module") else: timetableObj.addSession(d, s, t, m, "lab") return timetableObj
def createSchedule(self): #Do not change this line timetableObj = timetable.Timetable(1) tommy = list() tommy = self.moduleTutorList(self.tutorList, self.moduleList) self.backTrackTask1(tommy) self.timeTableIt(self.qwertyList, timetableObj) self.moduleTutorList(self.tutorList, self.moduleList) #Here is where you schedule your timetable #Do not change this line return timetableObj
def createSchedule(self): # Do not change this line timetableObj = timetable.Timetable(1) # Slot and list of days slot = [0, 1] days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] matches = {} # Loop through demographics for demo in self.demographic_list: matches[demo] = [] # Loop through comedians for com in self.comedian_list: match = True # If the comedian does not have all topics required for demographic skip for topic in demo.topics: if topic not in com.themes: match = False break # Otherwise add comedian to the list of demographic's matches if match: matches[demo].append(com) # Sort demographics by number of comedians that can perform them (ascending) matches = self.sort_dict(matches) # Loop through all possible matches for group in matches: selected = 0 # Select the first possible comedian selected_comedian = matches[group][selected] # If there is only one possible comedian if len(matches[group]) == 1: # Find a slot for it that does not violate constraints while not self.task1_constraints(selected_comedian, slot[0]): slot = self.task1_slots[self.task1_slots.index(slot) + 1] # If this match violates constraints then pick the next one while not self.task1_constraints( selected_comedian, slot[0]) and selected < len(matches[group]) - 1: selected += 1 selected_comedian = matches[group][selected] # Add match to timetable timetableObj.addSession(days[slot[0]], slot[1], selected_comedian, group, "main") # Add to the list of assigned matches self.assigned[tuple(slot)] = selected_comedian # DEBUG PRINT #print("Assigning " + selected_comedian.name + " to " + days[slot[0]]) # Get the next available slot slot = self.next_slot(slot, 1) # Do not change this line return timetableObj
def createMinCostSchedule(self): #Do not change this line timetableObj = timetable.Timetable(3) module_tutor_pairs = self.task_2_generate_module_tutor_pairs( timetableObj) self.task_2_generate_time_table_slot() self.task_2_can_solve_slot(timetableObj, module_tutor_pairs, 1) timetableObj = self.simulated_annealing(timetableObj) #Do not change this line return timetableObj
def solve_timetable(): rw = ReaderWriter.ReaderWriter() tutors, modules = rw.readRequirements("ExampleProblems/Problem4.txt") print(len(modules)) time_table = timetable.Timetable(2) module_tutor_pairs = generate_module_tutor_pairs(time_table, modules, tutors) generate_time_table_slot() # attempt to solve the task can_solve_slot(time_table, module_tutor_pairs, 1) print_timetable(time_table, tutors, modules) t = simulated_annealing(time_table, tutors, modules) print(t.cost)
def createLabSchedule(self): timetableObj = timetable.Timetable(2) # create variables to be used in backtrackLab count = 0 slots = list() orderedVariables = self.generateOrder2() # create ordered schedule of modules and labs without tutors assigned self.orderedSchedule2(timetableObj,orderedVariables) # call backtracking algorithm to create assignments self.backtrackLab(timetableObj,orderedVariables,slots,count) return timetableObj
def createSchedule(self): timetableObj = timetable.Timetable(1) # variables to be used in backtrack function count = 0 slots = list() # stores the slots that have been assigned orderedVariables = self.generateOrder() # create ordered schedule of modules without tutors assigned self.orderedSchedule(timetableObj, orderedVariables) # call backtracking algorithm to create assignments self.backtrack(timetableObj,orderedVariables,slots,count) return timetableObj
def set_(self, specsub, arg_timetable): # 初期化 count_spec = [[-1 for i2 in range(CLASS + 1)] for i1 in range(GRADE + 1)] for num in range(len(specsub)): if ('英' in specsub[num].subname or int( (specsub[num].subcode / 100) % 10) == 8 or int(specsub[num].subcode / 1000) == 8): if ('総英中' in specsub[num].subname): continue elif ('総英' in specsub[num].subname): pass else: continue grade = int(specsub[num].subcode / 1000) cla = int((specsub[num].subcode / 100) % 10) count_spec[grade][cla] += 1 day = SPECIAL[grade][cla - 1][count_spec[grade][cla]] % DAY time = int(SPECIAL[grade][cla - 1][count_spec[grade][cla]] / DAY) # 引数 args = { "subname": specsub[num].subname, "subcode": specsub[num].subcode, "teachernum": specsub[num].teachernum, "teachercode": specsub[num].teachercode, "fix_flag": False } arg_timetable[grade][cla][day][time] = timetable.Timetable(**args) if (specsub[num].cont != 0): for roop in range(1, specsub[num].cont + 1): arg_timetable[grade][cla][day][time + roop] = timetable.Timetable( **args)
def createLabSchedule(self): #Do not change this line timetableObj = timetable.Timetable(2) #Here is where you schedule your timetable #This line generates a random timetable, that may not be valid. You can use this or delete it. list1 = list() list1 = self.moduleTutorList(self.tutorList, self.moduleList) list2 = list() list2 = self.labTutorList(self.tutorList, self.moduleList) self.backTrackTask2(list1, self.qwertyList1, 2) self.backTrackTask2(list2, self.qwertyList2, 1) self.timeTableThat(timetableObj) #Do not change this line return timetableObj
def assignMainsAndTest(self, extendedDemoList, comediansNotBusy, assignments, demoNumber): tt = timetable.Timetable(2) # If we've reached assignments, we've finished so return true if demoNumber >= 50: return True # Get the demographic we're looking at in this recursion, and whether we're assigning a test for that demo, or a main demo = extendedDemoList[demoNumber][0] isTest = extendedDemoList[demoNumber][1] comediansNotBusy = self.applyAssignmentHeuristics( comediansNotBusy, demo, isTest, assignments) # For the new demographic, find the first comedian that can market it, and assign them to it for comedian, hours in comediansNotBusy.items(): if tt.canMarket(comedian, demo, isTest): # Can't use a dict for this one because of duplicate demos (1 test, 1 main) so use list of 3 element tuples t = [demo, comedian, isTest] newHours = 1 if isTest else 2 if hours >= newHours: # remove hours from comediansNotBusy comediansNotBusy.update({comedian: hours - newHours}) # remove comedian from available comics if hours left is 0 if hours == newHours: del comediansNotBusy[comedian] assignments.append(t) if self.assignMainsAndTest(extendedDemoList, comediansNotBusy, assignments, demoNumber + 1) == True: return True # If this assignment failed, remove it and add hours and comedian back to list removed = assignments.pop() comedian = removed[1] plusHours = 1 if removed[2] == True else 2 alreadyHours = 0 if comediansNotBusy.get( comedian) == None else comediansNotBusy.get(comedian) comediansNotBusy.update( {comedian: alreadyHours + plusHours}) return False
def createLabSchedule(self): # Create empty timetable timetableObj = timetable.Timetable(2) # Use backtracking algorithm to recursively schedule each module and # lab with a valid tutor to a given day schedule = self.backtrackingSearchLab() # Look-up list for day strings days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] # Populate the timetable object with all of the sessions in the schedule for day, sessions in enumerate(schedule): for slot, (module, tutor, type) in enumerate(sessions): # Record the session in the timetable with the approriate day and session number timetableObj.addSession(days[day], slot + 1, tutor, module, type) return timetableObj
def createMinCostSchedule(self): tt = timetable.Timetable(3) days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] assignments = [] timeslots = [None] * 50 output = [""] * 10 # Get a list of 50 shows, (1 test, 1 main for each demo) sorted by the number of comics that canMarket that show extendedDemoList = self.getSortedDemoList() # We're going to keep a list of comedians and their available time, so we can avoid trying to assign shows to fully-booked comedians comediansNotBusy = {} for comedian in self.comedian_List: comediansNotBusy.update({comedian: 4}) # Begin backtrack to find a valid pairing between demographics and comedians if self.assignMainsAndTest(extendedDemoList, comediansNotBusy, assignments, 0) == False: print( "No valid assignment of demographics (including tests) to comedians was found" ) return False sortedAssignments = sorted(assignments, key=lambda a: a[1].name) if self.assignShowsToDays(sortedAssignments, timeslots, 0) == False: print("No valid way of assigning those demographics to days (cap)") return False # Convert the list of timeslots & comic/show pairs into a timetable for i in range(50): day = self.getDay(i) session = (i % 10) d = timeslots[i][0] c = timeslots[i][1] t = timeslots[i][2] output[session] += (" T " if t else " M ") + c.name[:2] + " |" tt.addSession(days[day], session + 1, c, d, "test" if t else "main") for o in output: print(o) return tt
def createTestShowSchedule(self): timetableObj = timetable.Timetable(2) days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] assignments = [] # Get a list of 50 shows, (1 test, 1 main for each demo) sorted by the number of comics that canMarket that show extendedDemoList = self.getSortedDemoList() # We're going to keep a list of comedians and their available time, so we can avoid trying to assign shows to fully-booked comedians comediansNotBusy = {} for comedian in self.comedian_List: comediansNotBusy.update({comedian: 4}) # Begin backtrack to find a valid pairing between demographics and comedians if self.assignMainsAndTest(extendedDemoList, comediansNotBusy, assignments, 0) == False: print( "No valid assignment of demographics (including tests) to comedians was found" ) return False # Sort the list alphabetically by comedian name sortedList = sorted(assignments, key=lambda c: c[1].name) # Add all the demo/comedian pairs as sessions # Filling by session rather than day, in combination with our ordered list of pairs, means we'll never schedule a comedian for 2 sessions in one day for session in range(1, 11): out = " | " for day in range(5): # s counts from 0 to 49 s = (session - 1) * 5 + day isTest = sortedList[s][2] out += "T " if isTest else "M " out += sortedList[s][1].name[:2] + " | " test = "test" if isTest else "main" timetableObj.addSession(days[day], session, sortedList[s][1], sortedList[s][0], test) print(out) return timetableObj
def assignMains(self, assignments, demoNumber): tt = timetable.Timetable(1) # If we're reached 25 assignments, we've finished so return true if demoNumber >= 25: return True else: demo = self.demographic_List[demoNumber] # For the new demographic, find the first comedian that can market it, and assign them to it for comedian in self.comedian_List: if tt.canMarket(comedian, demo, False): # Assign the demo to the comedian assignments.update({demo: comedian}) # Check the 2 shows/wk constraint isn't violated if self.violationsMain(assignments) == False: # Recursively call assignMains with the newly added-to list of assignments, and the next demo to assign if self.assignMains(assignments, demoNumber + 1) == True: return True del assignments[demo] return False
def createMinCostSchedule(self): # Create empty timetable timetableObj = timetable.Timetable(3) # Asign a tutor to all 50 lab and module sessions using A* search algorithm tutor_modules, tutor_labs = self.findPairings() # Arrange all of the previously determined sessions into a legal # timetable schedule while minimising cost schedule = Scheduler.tableSessions(tutor_modules, tutor_labs) # Look-up list for day strings days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] # Populate the timetable object with all of the sessions in the schedule for day, sessions in enumerate(schedule): for slot, (module, tutor, type) in enumerate(sessions): # Record the session in the timetable with the approriate day and session number timetableObj.addSession(days[day], slot + 1, tutor, module, type) return timetableObj
def createSchedule(self): timetableObj = timetable.Timetable(1) days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] assignments = {} # Begin backtrack to find a valid pairing between demographics and comedians if self.assignMains(assignments, 0) == False: print("No valid assignment of demographics to comedians was found") return False # Sort the list alphabetically by comedian name sortedList = sorted(assignments.items(), key=lambda c: c[1].name) # Add all the demo/comedian pairs as sessions # Filling by session rather than day, in combination with our ordered list of pairs, means we'll never schedule a comedian for 2 sessions in one day for session in range(1, 6): for day in range(5): # s counts from 0 to 24 s = (session - 1) * 5 + day timetableObj.addSession(days[day], session, sortedList[s][1], sortedList[s][0], "main") return timetableObj