示例#1
0
def calc_score(courses, rooms, course_names, matrix):
    """
    Score calculation.
    """

    #  iterate through courses and set all scores to zero
    for course in courses:
        course.goodbad = 0

    # calculate points for all categories and add them
    points = 0
    points += sc.matrix_checker(courses, course_names, matrix) + sc.order_checker(courses)
    points += sc.student_checker(rooms, courses, course_names)
    dist_bonus, dist_malus = sc.distribution_checker(courses)
    points += dist_bonus + dist_malus
    points += sc.evening_checker(rooms, courses, course_names)

    return points
示例#2
0
def initial_population():
    """
    Initial population.
    """

    # store different schedules
    scheduled_rooms = [[] for i in range(5)]
    scheduled_courses = [[] for i in range(5)]
    scheduled_students = [[] for i in range(5)]
    scores = [0 for i in range(5)]
    matrix = []
    course_names = []
    matrixfile = open("data/matrix.csv", 'r')
    coursenamefile = open("data/vakken.txt", 'r')

    # read matrix
    for line in matrixfile:
        matrix.append(line.split(";"))

    for line in coursenamefile:
        course_names.append(line.split(";")[0])

    # schedule 5 times
    for i in range(5):

        #read files
        coursefile = open("data/vakken.txt", 'r')
        roomfile = open("data/lokalen.txt", 'r')
        studentfile = open("data/studentenenvakken.csv", 'r', errors='ignore')

        for line in coursefile:
            info = line.split(";")
            scheduled_courses[i].append(inf.Course(info[0], int(info[1]), int(info[2]), int(info[3]),\
                           int(info[4]), int(info[5]), int(info[7])))

        for line in roomfile:
            info = line.split(",")
            scheduled_rooms[i].append(inf.Room_info(info[0], int(info[1])))

        # create evening timeslot in largest room
        big_room_cap = 0

        for room in scheduled_rooms[i]:
            if room.cap > big_room_cap:
                big_room_cap = room.cap
                big_room = room

        for day in big_room.days:
            day.hours.append(inf.Hour())

        for line in studentfile:
            student_info = line.strip("\n").split(";")
            student_courses = []
            for coursename in student_info[3:]:
                if len(coursename) > 2:
                    student_courses.append(coursename)

            scheduled_students[i].append(
                inf.Student(student_info[0], student_info[1], student_info[2],
                            student_courses))

        # remove headers in students
        scheduled_students[i] = scheduled_students[i][1:]

        # schedule
        day_sch.total_schedule(scheduled_rooms[i], scheduled_courses[i],
                               course_names, matrix)

        # calculate score and apply hillclimber
        scores[i] = sc.matrix_checker(scheduled_courses[i], course_names,
                                      matrix) + sc.order_checker(
                                          scheduled_courses[i])
        scores[i] += sc.student_checker(scheduled_rooms[i],
                                        scheduled_courses[i], course_names)
        bonus, malus = sc.distribution_checker(scheduled_courses[i])
        scores[i] += bonus + malus
        scores[i] += sc.evening_checker(scheduled_rooms[i],
                                        scheduled_courses[i], course_names)
        scores[i] = hill.random_climber(scheduled_courses[i],
                                        scheduled_rooms[i], course_names, 1000,
                                        scores[i], matrix)

        # schedule students
        stu.distribute_all_students(scheduled_students[i], scheduled_rooms[i],
                                    scheduled_courses[i], course_names)

        # Save score for hillclimber
        student_bonus, student_malus = sc.student_score(scheduled_students[i])
        student_score = student_bonus + student_malus

        # pre filter the relevant courses
        student_courses = []
        for course in scheduled_courses[i]:
            poss_group_ids = []

            for activity in course.activities:
                if activity.group_id not in poss_group_ids and activity.group_id != "x":
                    poss_group_ids.append(activity.group_id)

            if len(poss_group_ids) > 1:
                student_courses.append([course, poss_group_ids])

        # student hillclimber
        scores[i] += sthl.students_hillclimber(student_courses,
                                               scheduled_students[i],
                                               student_score, 100)

    return scheduled_rooms, scheduled_courses, scheduled_students, scores, course_names, matrix
示例#3
0
def mutate_schedule(rooms, courses, students, score, matrix, course_names):
    """
    Mutate a fit schedule to 10 different schedules. Keep the orignal schedule.
    Furthermore, for 9 times: unschedule a random subset of the courses and
    reschedule this subset.
    """

    # store mutated schedules
    new_rooms = [[inf.Room_info(room.name, room.cap) for room in rooms] \
        for j in range(10)]

    new_courses = [[inf.Course(course.name, course.hoorcolleges, \
        course.werkcolleges, course.max_werkcolleges, course.practica, \
            course.max_practica, course.e_students) for course in courses] \
                for j in range(10)]

    new_students = [[inf.Student(student.surname, student.name, \
        student.student_number, student.courses) for student in students] \
            for j in range(10)]

    new_scores = [0 for j in range(10)]

    # create evening timeslot in largest room
    for n_rooms in new_rooms:

        big_room_cap = 0

        for room in n_rooms:
            if room.cap > big_room_cap:
                big_room_cap = room.cap
                big_room = room

        for day in big_room.days:
            day.hours.append(inf.Hour())

    # copy orignal schedule onto mutations
    for k in range(10):
        new_rooms[k], new_courses[k], new_students[k] = bas_sch.copy_schedule(rooms, \
            courses, students, new_rooms[k], new_courses[k], new_students[k])

    # keep original schedule
    new_scores[0] = score

    # mutate 9 times
    for i in range(1, 10):

        # select random subset of scheduled courses
        indices = rd.sample(range(len(new_courses[i])), rd.randint(0, \
            len(new_courses[i]) - 7))

        # store names of subset
        unsched_names = []

        # unschedule subset
        for j in indices:
            unsched_names.append(new_courses[i][j].name)
            clear_schedule_of_course(new_rooms[i], new_courses[i][j], \
                new_students[i])

        # schedule all required classes
        schedulings = 0
        for j in indices:
            schedulings += day_sch.course_scheduler(new_courses[i][j], new_rooms[i],\
                new_courses[i], course_names, matrix)
        print("Schedulings:", schedulings)

        # schedule students' unscheduled groups
        for student in new_students[i]:
            for coursename in student.courses:
                if coursename in unsched_names:
                    course = new_courses[i][course_names.index(coursename)]
                    poss_group_ids = []
                    student_id = ""

                    # get possible groups of course for student and choose one randomly
                    for activity in course.activities:
                        if activity.group_id != "x" and len(
                                activity.students) < activity.capacity:
                            poss_group_ids.append(activity.group_id)
                    if len(poss_group_ids) > 0:
                        student_id = rd.choice(poss_group_ids)

                    student.group_id[student.courses.index(
                        course.name)] = student_id

                    # schedule student
                    for activity in course.activities:
                        if activity.id == "Hoorcollege" or activity.group_id == student_id:
                            activity.students.append(student.student_number)
                            student.dates[student.courses.index(
                                coursename)].append(activity.date)

        # calculate score
        new_scores[i] = sc.matrix_checker(new_courses[i], course_names, \
            matrix) + sc.order_checker(new_courses[i])
        new_scores[i] += sc.student_checker(new_rooms[i], new_courses[i],
                                            course_names)
        bonus, malus = sc.distribution_checker(new_courses[i])
        new_scores[i] += bonus + malus + sc.evening_checker(new_rooms[i], \
            new_courses[i], course_names)
        student_bonus, student_malus = sc.student_score(new_students[i])
        new_scores[i] += student_bonus + student_malus

    return new_rooms, new_courses, new_students, new_scores
示例#4
0
    for room in rooms:
        if room.cap > big_room_cap:
            big_room_cap = room.cap
            big_room = room

    for day in big_room.days:
        day.hours.append(inf.Hour())

    course_names = [course.name for course in courses]

    # return total score of schedule using the score calculator
    day_sch.total_schedule(rooms, courses, course_names, matrix)
    score = sc.matrix_checker(courses, course_names,
                              matrix) + sc.order_checker(courses)
    score += sc.student_checker(rooms, courses, course_names)
    bonus, malus = sc.distribution_checker(courses)
    score += bonus + malus
    score += sc.evening_checker(rooms, courses, course_names)

    # print scores before hillclimber
    if not course_optim_type == "none":
        print("Courses score before optimization:", score)

        # for course in courses:
        #     if course.goodbad < - 1000:
        #         score = hill.course_climber(courses[0], courses, rooms, course_names, 1000, score, matrix)
        #         print("Score after 1 course_climb: ", score)

        # run hillclimber if specified by user
        if course_optim_type == "hillclimber":
            score = hill.random_climber(courses, rooms, course_names,
示例#5
0
def search(rooms, courses, course_names, students, matrix):
    """
    Searches for painpoints in the case.
    """

    student_numbers = [student.student_number for student in students]
    student_weakness = [0 for number in student_numbers]
    course_weakness = [0 for coursename in course_names]

    for i in range(100):

        # schedule
        day_sch.total_schedule(rooms, courses, course_names, matrix)

        # calculate score and apply hillclimber
        score = sc.matrix_checker(courses, course_names,
                                  matrix) + sc.order_checker(courses)
        score += sc.student_checker(rooms, courses, course_names)
        bonus, malus = sc.distribution_checker(courses)
        score += bonus + malus
        score += sc.evening_checker(rooms, courses, course_names)
        score = hill.random_climber(courses, rooms, course_names, 1000, score,
                                    matrix)

        # schedule students
        stu.distribute_all_students(students, rooms, courses, course_names)

        # save score for hillclimber
        student_bonus, student_malus = sc.student_score(students)
        student_score = student_bonus + student_malus

        # pre filter the relevant courses
        student_courses = []
        for course in courses:
            poss_group_ids = []

            for activity in course.activities:
                if activity.group_id not in poss_group_ids and activity.group_id != "x":
                    poss_group_ids.append(activity.group_id)

            if len(poss_group_ids) > 1:
                student_courses.append([course, poss_group_ids])

        # student hillclimber
        student_climb_score = sthl.students_hillclimber(
            student_courses, students, student_score, 100)

        # update statistics
        for course in courses:
            if course.goodbad < 0:
                course_weakness[course_names.index(course.name)] += 1
        for student in students:
            if student.goodbad < -12:
                student_weakness[student_numbers.index(
                    student.student_number)] += 1

        bas_sch.print_schedule(rooms)
        bas_sch.clear_schedule(rooms, courses)
        bas_sch.clear_students(students)
        cprint(i, "blue")

    # print painpoints
    for f in range(len(student_numbers)):
        print(student_numbers[f] + ":", student_weakness[f])
    for j in range(len(course_names)):
        print(course_names[j] + ":", course_weakness[j])