-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathestimator.py
executable file
·139 lines (116 loc) · 4.23 KB
/
estimator.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
128
129
130
131
132
133
134
135
136
137
138
139
import networkx as nx
from parse import *
from utils import *
import sys
import os
import time
import random
import math
''' simulated annealing bay bee
G: the graph of the students and their breakout rooms
samples_per: how many members are in each generation
kept_per: how many solutions to keep in each generation
loops: how many generations to process
seed: seed for the rng
TODO: This is just gradient descent atm, probably should add a chance to consider
horrible solutions for reasons described in textbook
also i am clearly not going to have time to finish this tonight i am so tired
'''
def estimate(G, s):
return greedy_solution(G, s)
def greedy_solution(G, budget):
"""
Hill climbing solution
Returns:
"""
numStudents = len(G.nodes)
assignment = {} # maps student to rooms
for s in range(numStudents):
assignment[s] = s
counter = 0
timeout = 480
move = getBetterAssignment(G, budget, assignment, numStudents)
start = time.time()
good = 1
while good and time.time() < start + timeout:
good = getBetterAssignment(G, budget, assignment, numStudents)
counter += 1
return assignment, len(set(assignment.values()))
def schedule(t):
return 0.49 * math.exp(-0.07 * t)
def randomMove(G, s, D, maxRooms):
start = time.time()
maxHappiness = calculate_happiness(D, G)
student = None
move = None
random_students = random.sample(list(range(len(G.nodes))), len(list(range(len(G.nodes)))))
random_rooms = random.sample(list(range(maxRooms)), maxRooms)
#print(range(len(G.nodes)))
for curStudent in random_students:
oldRoom = D[curStudent]
for newRoom in random_rooms:
D[curStudent] = newRoom
if is_valid_solution(D, G, s, len(set(D.values()))):
D[curStudent] = oldRoom
return curStudent, newRoom
D[curStudent] = oldRoom
if student is None:
return None
print("random took", time.time() - start)
return student, move
def getBetterAssignment(G, s, D, maxRooms):
start = time.time()
maxHappiness = calculate_happiness(D, G)
student = None
move = None
backup = D.copy()
for curStudent in list(range(len(G.nodes))):
oldRoom = D[curStudent]
for newRoom in list(range(maxRooms)):
D[curStudent] = newRoom
if is_valid_solution(D, G, s, len(set(D.values()))):
newHappiness = calculate_happiness(D, G)
if maxHappiness < newHappiness:
maxHappiness = newHappiness
student = curStudent
move = newRoom
D[curStudent] = oldRoom
single_swap_max_hap = maxHappiness
assert D == backup
best_pair = (-1, -1)
for stud1 in range(len(G.nodes)):
for stud2 in range(stud1 + 1, len(G.nodes)):
if D[stud1] == D[stud2]:
continue
D[stud1], D[stud2] = D[stud2], D[stud1]
if is_valid_solution(D, G, s, len(set(D.values()))):
newHappiness = calculate_happiness(D, G)
if newHappiness < maxHappiness:
maxHappiness = newHappiness
best_pair = (stud1, stud2)
D[stud1], D[stud2] = D[stud2], D[stud1]
if student == None and best_pair == (-1, -1):
return 0
assert D == backup
if maxHappiness > single_swap_max_hap:
stud1, stud2 = best_pair[0], best_pair[1]
D[stud1], D[stud2] = D[stud2], D[stud1]
else:
D[student] = move
return 1
if __name__ == "__main__":
for fname in sorted(os.listdir("shits_/")):
if fname[:-3] + ".out" not in os.listdir("twowide"):
print('pseudo greedying', fname)
path = os.path.join("shits_", fname)
G, s = read_input_file(path)
start = time.time()
D, k = estimate(G, s)
end = time.time()
assert is_valid_solution(D, G, s, k)
print("Total Happiness: {}".format(calculate_happiness(D, G)))
print("Solving took {} seconds.".format(end - start))
if path[-3:] == ".in":
write_output_file(D, f'twowide/{path[7:-3]}.out')
else:
write_output_file(D, f'test/test.out')