-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscoreFunction.py
executable file
·127 lines (101 loc) · 3.7 KB
/
scoreFunction.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""
Author: Corneel den Hartogh
Course: Heuristics
Description: Python implementation of the given score function
"""
from decimal import Decimal
def getScore(roster):
timetable = roster.timetable
activities = roster.activities
students = roster.students
subjects = roster.subjects
classrooms = roster.classrooms
# Every timetable is 'valid' so the 1000 points are easy made
valid = 1000
# The large room has extra slot, usage costs 50 points:
escapeRoom = 0
for key in timetable:
if key[1] == 4:
escapeRoom -= 50
# One point is detracted for every student that doesn't fit in the room
capacityOverload = 0
for activity in activities:
if classrooms[activity.slot[2]].capacity < len(activity.students):
capacityOverload += (classrooms[activity.slot[2]].capacity - len(activity.students))
# One point is detracted for every moment (the first two values of the tuple-slot) that a students has 2 activities
studentConflict = 0
for student in students:
slots = []
for activity in student.activities:
slots.append(activity.slot[0:2])
studentConflict -= (len(slots) - len(set(slots)))
subjectEvenlySpread = 0
overlapScore = 0
for subject in subjects:
subjectResult = prepareSubjectScore(subject)
overlapScore += subjectResult[0]
subjectEvenlySpread += subjectResult[1]
# final score
studentScore = capacityOverload + studentConflict
subjectScore = overlapScore + subjectEvenlySpread
score = valid + escapeRoom + studentScore + subjectScore
#print(score, escapeRoom, capacityOverload, studentConflict, overlapScore, subjectEvenlySpread)
#print(score)
return score
def prepareSubjectScore(subject):
# a subject that is spread evenly over the week is worth 20 points. However, some subjects have multiple groups
# for worklectures and practica. For those I calculate for all the groups whether they qualify for 20 points. The
# aggregated score is then divided by the number of groups to ensure a subject cannot score more than 20 points
lectures, workLectures, practicas = [], [], []
for activity in subject.activities:
if activity.kind == "WorkLecture":
workLectures.append(activity.slot[0])
if activity.kind == "Practicum":
practicas.append(activity.slot[0])
if activity.kind == "Lecture":
lectures.append(activity.slot[0])
i, j = 0, 0
if workLectures and practicas:
num = len(workLectures) * len(practicas)
for wl in workLectures:
for pr in practicas:
[i,j] = getSpreadOverlapScore(i,j, lectures + [wl] + [pr])
elif workLectures or practicas:
num = len(workLectures) + len(practicas)
for act in workLectures + practicas:
[i,j] = getSpreadOverlapScore(i,j, lectures + [act])
else:
num = 1
[i,j] = getSpreadOverlapScore(i,j, lectures)
#overlapScore -= Decimal(str(i / num)).quantize(Decimal('.01'))
#subjectEvenlySpread += Decimal(str(j / num)).quantize(Decimal('.01'))
return [Decimal(str(i / num)).quantize(Decimal('.01')), Decimal(str(j / num)).quantize(Decimal('.01'))]
def getSpreadOverlapScore(i, j, combiActivities):
overlapScore = (len(combiActivities) - len(set(combiActivities))) * -10
spreadScore = 0
# if there is overlap no ideal spread is possible
if overlapScore == 0:
combiActivities.sort()
if len(combiActivities) == 2:
if combiActivities == [0,3] or combiActivities == [1,4]:
spreadScore = 20
else:
spreadScore = 0
elif len(combiActivities) == 3:
if combiActivities == [0,2,4]:
spreadScore = 20
else:
spreadScore = 0
elif len(combiActivities) == 4:
if combiActivities == [0,1,3,4]:
spreadScore = 20
else:
spreadScore = 0
elif len(combiActivities) == 5:
if combiActivities == [0,1,2,3,4]:
spreadScore = 20
else:
spreadScore = 0
i += overlapScore
j += spreadScore
return [i , j]