def main(): """ free = [(row, column)...] - list of free fields (row, column) in matrix filled: dictionary where key = index of the class, value = list of fields in matrix subjects_order: dictionary where key = (name of the subject, index of the group), value = [int, int, int] where ints represent start times (row in matrix) for types of classes P, V and L respectively groups_empty_space: dictionary where key = group index, values = list of rows where it is in teachers_empty_space: dictionary where key = name of the teacher, values = list of rows where it is in matrix = columns are classrooms, rows are times, each field has index of the class or it is empty data = input data, contains classes, classrooms, teachers and groups """ filled = {} subjects_order = {} groups_empty_space = {} teachers_empty_space = {} file = 'ulaz1.txt' data = load_data('test_files/' + file, teachers_empty_space, groups_empty_space, subjects_order) print(len(data.classrooms)) matrix, free = set_up(len(data.classrooms)) print(free) initial_population(data, matrix, free, filled, groups_empty_space, teachers_empty_space, subjects_order) total, _, _, _, _ = hard_constraints_cost(matrix, data) print('Initial cost of hard constraints: {}'.format(total)) evolutionary_algorithm(matrix, data, free, filled, groups_empty_space, teachers_empty_space, subjects_order) print('STATISTICS') show_statistics(matrix, data, subjects_order, groups_empty_space, teachers_empty_space) simulated_hardening(matrix, data, free, filled, groups_empty_space, teachers_empty_space, subjects_order, file)
def main(): filled = {} subjects_order = {} groups_empty_space = {} teachers_empty_space = {} file = 'in.txt' data = load_data('test_files/' + file, teachers_empty_space, groups_empty_space, subjects_order) matrix, free = set_up(len(data.classrooms)) initial_population(data, matrix, free, filled, groups_empty_space, teachers_empty_space, subjects_order) total, _, _, _, _ = hard_constraints_cost(matrix, data) print('Initial cost of hard constraints: {}'.format(total)) evolutionary_algorithm(matrix, data, free, filled, groups_empty_space, teachers_empty_space, subjects_order) print('STATISTICS') start_time = time.time() # For serial # simulated_hardening(matrix, data, free, filled, groups_empty_space, teachers_empty_space, subjects_order, file) # For parallel for i in range(5): threads = [None] * 5 results = [None] * 5 for i in range(len(threads)): threads[i] = Thread(target=simulated_hardening_utils, args=(matrix, data, free, filled, groups_empty_space, teachers_empty_space, subjects_order, results, i)) threads[i].start() for i in range(len(threads)): threads[i].join() min = 1000 index = 0 for item in range(len(results)): if results[item][0] < min: index = item min = results[item][0] print("==== Min cost is %s ====", results[index][0]) matrix, free, filled, groups_empty_space, teachers_empty_space, subjects_order = results[ index][1:] print("--- %s seconds ---" % (time.time() - start_time)) show_statistics(matrix, data, subjects_order, groups_empty_space, teachers_empty_space) write_solution_to_file(matrix, data, filled, file, groups_empty_space, teachers_empty_space, subjects_order)
def evolutionary_algorithm(matrix, data, free, filled, groups_empty_space, teachers_empty_space, subjects_order): """ Evolutionary algorithm that tires to find schedule such that hard constraints are satisfied. It uses (1+1) evolutionary strategy with Stifel's notation. """ n = 3 sigma = 2 run_times = 5 max_stagnation = 200 for run in range(run_times): print('Run {} | sigma = {}'.format(run + 1, sigma)) t = 0 stagnation = 0 cost_stats = 0 while stagnation < max_stagnation: # check if optimal solution is found loss_before, cost_classes, cost_teachers, cost_classrooms, cost_groups = hard_constraints_cost( matrix, data) if loss_before == 0 and check_hard_constraints(matrix, data) == 0: print('Found optimal solution: \n') show_timetable(matrix) break # sort classes by their loss, [(loss, class index)] costs_list = sorted(cost_classes.items(), key=itemgetter(1), reverse=True) # 10*n for i in range(len(costs_list) // 4): # mutate one to its ideal spot if random.uniform(0, 1) < sigma and costs_list[i][1] != 0: mutate_ideal_spot(matrix, data, costs_list[i][0], free, filled, groups_empty_space, teachers_empty_space, subjects_order) # else: # # exchange two who have the same duration # r = random.randrange(len(costs_list)) # c1 = data.classes[costs_list[i][0]] # c2 = data.classes[costs_list[r][0]] # if r != i and costs_list[r][1] != 0 and costs_list[i][1] != 0 and c1.duration == c2.duration: # exchange_two(matrix, filled, costs_list[i][0], costs_list[r][0]) loss_after, _, _, _, _ = hard_constraints_cost(matrix, data) if loss_after < loss_before: stagnation = 0 cost_stats += 1 else: stagnation += 1 t += 1 # Stifel for (1+1)-ES if t >= 10 * n and t % n == 0: s = cost_stats if s < 2 * n: sigma *= 0.85 else: sigma /= 0.85 cost_stats = 0 print( 'Number of iterations: {} \nCost: {} \nTeachers cost: {} | Groups cost: {} | Classrooms cost:' ' {}'.format(t, loss_after, cost_teachers, cost_groups, cost_classrooms))