-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerador.py
156 lines (128 loc) · 4.44 KB
/
generador.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# Función de comparación para el ordenamiento por selección.
def comp(a, b):
if a%2 == 0:
if b%2 == 0:
if a <= b: return True
return False
return True
else:
if b%2 == 0: return False
if a <= b: return True
return False
# Ordenamiento por selección.
def sort(u, v, w):
n = len(u)
for i in range(0, n):
min = u[i]
posMin = i
for j in range(i + 1, n):
if comp(u[j], min):
min = u[j]
posMin = j
u[i], u[posMin] = u[posMin], u[i]
v[i], v[posMin] = v[posMin], v[i]
w[i], w[posMin] = w[posMin], w[i]
# Primera asignación de horas al fin de semana.
def update_finde(hours):
n = len(hours)
finde = [0]*n
ht = 0
for i in range(0, n): ht += hours[i]
hf = int((ht*2)/7)
if hf%2 != 0: hf -= 1
i = n - 1
while hf > 0:
hf -= 2
hours[i] -= 2
finde[i] += 2
i -= 1
# Si me he salido de la lista, vuelvo a comenzar.
if i < 0: i = n - 1
return finde
# Añadir 1 hours de estudio de asig en day.
def put1(asig, day, horario):
for i in range(0, len(horario)):
if horario[i][day] == -2:
horario[i][day] = asig
return True
return False
# Añadir 2 hours de estudio de asig en day.
def put2(asig, day, horario):
for i in range(0, len(horario) - 1):
if horario[i][day] == -2 and horario[i + 1][day] == -2:
horario[i][day] = horario[i + 1][day] = asig
return True
return False;
# Retorna verdadero si un día está completo.
def complete(horario, day):
n = len(horario)
for i in range(0, n):
if horario[i][day] == -2: return False
return True
# Devuelve el día con menos hours de estudio no completo.
def next_minimum_uncomplete(horario, hras_est_dia):
minDay = -1
for day in range(0, 5):
if not complete(horario, day) and \
(minDay == -1 or hras_est_dia[day] < hras_est_dia[minDay]):
minDay = day
return minDay
def distribute(hours, horario, finde):
hras_est_dia = [0]*5
n = len(hours) # Número de asignaturas.
# En grupos de 2 hours.
# Secuencia: Lunes, Miércoles, Viernes, Martes, Jueves.
sec = [0, 2, 4, 1, 3]
j = 0 # Iterador para la secuencia de días.
for asig in range(0, n):
exit = 0
while hours[asig] > 1 and exit < 5:
if j > 4: j = 0
if put2(asig, sec[j], horario):
hours[asig] -= 2
hras_est_dia[sec[j]] += 2
else: exit += 1
j += 1
# Para que no se quede una asignatura con más de 4 hours para el fin de semana.
for asig in range(0, n):
bug = 0 # Para evitar bucle infinito.
while hours[asig] + finde[asig] > 4 and bug < 3:
bug += 1
day = next_minimum_uncomplete(horario, hras_est_dia)
if day != -1 and put1(asig, day, horario):
hours[asig] -= 1
hras_est_dia[day] += 1
# De 1 hora en 1 hora. Comenzando por los días con menos hours de estudio.
for asig in range(0, n):
finished = False
while hours[asig] > 0 and not finished:
day = next_minimum_uncomplete(horario, hras_est_dia)
if day == -1: finished = True
elif put1(asig, day, horario):
hours[asig] -= 1
hras_est_dia[day] += 1
# Guardando las hours no asignadas en vector fin de semana.
for i in range(0, n):
finde[i] += hours[i]
hours[i] = 0
def generator_main(horas, nombres_des, horario):
# Creo copia del vector de horas y de nombres, para no sobreescribirlo.
hours = list(horas)
nombres = list(nombres_des)
sort(hours, nombres, [0]*len(hours))
finde = update_finde(hours)
sort(hours, nombres, finde)
distribute(hours, horario, finde)
# Convirtiendo el horario codificado, a horario con nombres.
for i in range(0, len(horario)):
for j in range(0, 5):
k = horario[i][j]
if k >= 0: horario[i][j] = nombres[k]
elif k == -1: horario[i][j] = '-----------------'
else: horario[i][j] = ''
# Reordenando el vector finde, como nombres_des.
finde_des = []
for i in range(0, len(finde)):
pos = nombres.index(nombres_des[i])
finde_des.append(finde[pos])
return finde_des;