-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimulatedAnnealing.py
executable file
·114 lines (84 loc) · 3.43 KB
/
simulatedAnnealing.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
"""
Author: Corneel den Hartogh
Course: Heuristics
Description: Simulated Annealing algorithm code
"""
import random
import copy
import time
import math
from decimal import Decimal
from csvFilesController import classrooms,subjects,students
from classes import Classroom,Subject,Activity,Student,Roster
from scoreFunction import getScore
from studentOptimization import studentOptimization
from roomOptimization import roomOptimization
def simulatedAnnealing():
startTime = time.process_time()
bestRoster = Roster(classrooms,subjects, students)
bestRoster.fillInRoster()
bestScore = getScore(bestRoster)
allTimeBestScore = bestScore
iteration = 0
scores = []
scores.append([bestScore,0])
temp = 100
# due to temperature it becomes after 30 a hillclimber (so that's where I cross the line)
while iteration < 30 or scores[-1][0] > scores[-2][0]:
t = 0
period = 1000
while t < period:
newRoster = Roster(classrooms,subjects,students)
newRoster = Roster.duplicateRoster(newRoster,bestRoster)
newRoster.getSlot()
slotOne = newRoster.slot
newRoster.getSlot()
slotTwo = newRoster.slot
slots = [slotOne, slotTwo]
activities = []
#swap the activities (if any) of two slots
for index, slot in enumerate(slots):
if slot in newRoster.timetable:
activities.append(newRoster.timetable[slot])
else:
activities.append(None)
for i, activity in enumerate(activities):
for j, slot in enumerate(slots):
if i != j:
if activity is not None:
newRoster.timetable[slot] = activity
activity.slot = slot
else:
if activities[j] is not None:
del newRoster.timetable[slot]
# make sure students are sorted appropriately over the WorkLectures and Practica
# get the timeslots (first 2 values of slot) of the activities and keep only the one's that are double rostered
newRoster = studentOptimization(newRoster)
newRoster = roomOptimization(newRoster)
score = getScore(newRoster)
delta = score - bestScore
if delta > 0:
bestRoster = newRoster
bestScore = score
iBest = (iteration*period)+ t
if score > allTimeBestScore:
allTimeBestScore = score
allTimeBestRoster = newRoster
allTImeBestI = (iteration*period)+t
else:
p = math.exp(delta / Decimal(temp))
if random.random() < p :
bestRoster = newRoster
bestScore = score
iBest = (iteration*period)+ t
temp = 100 * math.pow(10 / 100,((iteration*period)+t)/10000)
t += 1
#print(bestScore)
scores.append([allTimeBestScore, allTImeBestI])
iteration +=1
runtime = time.process_time() - startTime
#print(bestScore, iBest, ((iteration-1)*period))
#print(allTimeBestScore, allTImeBestI)
allTimeBestRoster.exportRoster("annealing",allTimeBestScore,runtime)
#print("--- %s seconds ---" % (runtime))
simulatedAnnealing()