예제 #1
0
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)
예제 #3
0
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))