def generar_restriccion_si_se_elige_un_curso_se_cursa_su_horario_completo( arch, parametros): arch.write( "#Si la materia se cursa en ese cuatrimestre en ese curso en particular, entonces se deben cursar todos los horarios del mismo" + ENTER + ENTER) for cuatri in range(1, parametros.max_cuatrimestres + 1): for id_materia in parametros.horarios: cursos = parametros.horarios[id_materia] for curso in cursos: H = "H_{}_{}_{}".format(id_materia, curso.id_curso, get_str_cuatrimestre(cuatri)) if not es_horario_valido_para_el_cuatrimestre( parametros, curso, cuatri): continue for c_horario in curso.horarios: dia = c_horario.dia franjas = c_horario.get_franjas_utilizadas() for franja in franjas: R = "R_{}_{}_{}_{}_{}".format( id_materia, curso.id_curso, dia, franja, get_str_cuatrimestre(cuatri)) arch.write("prob += ({} <= {})".format(H, R) + ENTER) arch.write("prob += ({} >= {})".format(H, R) + ENTER) arch.write(ENTER)
def generar_restriccion_maxima_cant_materias_por_cuatrimestre( arch, parametros): arch.write( "# La cantidad de materias por cuatrimestre no puede superar un valor maximo" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): ecuacion = "prob += (" for id_materia in parametros.plan: variable = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(cuatrimestre)) ecuacion += variable + " + " if not parametros.materia_trabajo_final: ecuacion = ecuacion[:-2] else: for materia in parametros.materia_trabajo_final: variable = "Y_TP_FINAL_{}_{}_{}".format( materia.id_materia, materia.codigo, get_str_cuatrimestre(cuatrimestre)) ecuacion += variable + " + " ecuacion = ecuacion[:-2] ecuacion += " <= {})".format( parametros.max_cant_materias_por_cuatrimestre) arch.write(ecuacion + ENTER) arch.write(ENTER + ENTER)
def generar_restriccion_maxima_cantidad_horas_extra_cursada(arch, parametros): arch.write( "# Maxima cantidad de horas extra cursada. El calculo es por una semana en medias" "horas de cursada, pero es la misma restriccion para todo el cuatrimestre" + ENTER + ENTER) for i in range(1, parametros.max_cuatrimestres + 1): ecuacion = "prob += (" for id_materia in parametros.plan: materia = parametros.materias[id_materia] variable_Y = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(i)) ecuacion += "{}*{} + ".format(materia.medias_horas_extras_cursada, variable_Y) if not parametros.materia_trabajo_final: ecuacion = ecuacion[:-2] # elimino el ultimo + agregado else: for materia in parametros.materia_trabajo_final: variable_Y = "Y_TP_FINAL_{}_{}_{}".format( materia.id_materia, materia.codigo, get_str_cuatrimestre(i)) ecuacion += "{}*{} + ".format( materia.medias_horas_extras_cursada, variable_Y) ecuacion = ecuacion[:-2] # elimino el ultimo + agregado arch.write(ecuacion + " <= {})".format(parametros.max_horas_extras) + ENTER) arch.write(ENTER)
def generar_restriccion_calculo_creditos_obtenidos_por_cuatrimestre( arch, parametros): arch.write("# Calculo de creditos al terminar cada cuatrimestre" + ENTER + ENTER) for i in range(1, parametros.max_cuatrimestres + 1): ecuacion = "prob += (" for id_materia in parametros.plan: materia = parametros.materias[id_materia] variable_Y = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(i)) ecuacion += "{}*{} + ".format(materia.creditos, variable_Y) if not parametros.materia_trabajo_final: ecuacion = ecuacion[:-2] # elimino el ultimo + agregado else: for materia in parametros.materia_trabajo_final: variable_Y = "Y_TP_FINAL_{}_{}_{}".format( materia.id_materia, materia.codigo, get_str_cuatrimestre(i)) ecuacion += "{}*{} + ".format(materia.creditos, variable_Y) ecuacion = ecuacion[:-2] # elimino el ultimo + agregado if i > 1: ecuacion += "+ CRED{}".format(get_str_cuatrimestre(i - 1)) else: ecuacion += "+ {}".format(parametros.creditos_preacumulados) arch.write(ecuacion + " <= CRED{})".format(get_str_cuatrimestre(i)) + ENTER) arch.write(ecuacion + " >= CRED{})".format(get_str_cuatrimestre(i)) + ENTER) arch.write(ENTER)
def generar_restriccion_solo_puede_cursarse_en_un_lugar_al_mismo_tiempo( arch, parametros): arch.write( "#No hay giratiempos: Solo puede cursarse una materia en un unico curso en el mismo horario" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for dia in parametros.dias: for franja in range(parametros.franja_minima, parametros.franja_maxima + 1): ec_suma = "" for id_materia in parametros.horarios: for curso in parametros.horarios[id_materia]: if not es_horario_valido_para_el_cuatrimestre( parametros, curso, cuatrimestre): continue if es_horario_restriccion_valido(curso, dia, franja): ec_suma += "R_{}_{}_{}_{}_{} + ".format( id_materia, curso.id_curso, dia, franja, get_str_cuatrimestre(cuatrimestre)) ec_suma = ec_suma[:-3] if not ec_suma: ec_suma = "0" ecuacion = "prob += ({}_{}_{} {} ".format( dia, franja, get_str_cuatrimestre(cuatrimestre), '{}') + ec_suma + ")" arch.write(ecuacion.format("<=") + ENTER) arch.write(ecuacion.format(">=") + ENTER) arch.write(ENTER)
def generar_restriccion_si_la_materia_no_se_cursa_en_ese_cuatrimestre_no_se_cursa_ninguno_de_sus_cursos( arch, parametros): arch.write( "# Si la materia no se cursa ese cuatrimestre, entonces no puede cursarse en ninguno de los cursos de ese cuatrimestre" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for id_materia in parametros.horarios: for curso in parametros.horarios[id_materia]: Y = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(cuatrimestre)) R = "H_{}_{}_{}".format(id_materia, curso.id_curso, get_str_cuatrimestre(cuatrimestre)) ecuacion = "prob += ({} >= {})".format(Y, R) arch.write(ecuacion + ENTER) arch.write(ENTER)
def generar_restriccion_creditos_minimos_electivas(arch, parametros): if parametros.creditos_minimos_electivas == 0: return arch.write( "#Se debe realizar un minimo de creditos de materias electivas" + ENTER + ENTER) ecuacion = "prob += (" for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for id_materia in parametros.materias: materia = parametros.materias[id_materia] if materia.tipo == OBLIGATORIA: continue Y = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(cuatrimestre)) ecuacion += Y + "*" + str(materia.creditos) + " + " ecuacion = ecuacion[:-3] # FIXME: Esto no anda por algun motivo. Solucion temporal, colocar que no supere los creditos en electivas por mas de 6 # arch.write(ecuacion + " <= CREDITOS_ELECTIVAS)" + ENTER) # arch.write(ecuacion + " >= CREDITOS_ELECTIVAS)" + ENTER) # arch.write("prob += (CREDITOS_ELECTIVAS >= " + str(parametros.creditos_minimos_electivas) + ")" + ENTER + ENTER) CREDITOS_UNA_MATERIA_EXTRA = 6 arch.write(ecuacion + " >= " + str(parametros.creditos_minimos_electivas) + ")" + ENTER + ENTER) arch.write(ecuacion + " <= " + str(parametros.creditos_minimos_electivas + CREDITOS_UNA_MATERIA_EXTRA) + ")" + ENTER + ENTER)
def obtener_sumatoria_Y_cuatrimestres_para_materia(parametros, materia): sumatoria = "" for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): variable = "Y_{}_{}".format(materia.id_materia, get_str_cuatrimestre(cuatrimestre)) sumatoria += variable + " + " return sumatoria[:-3]
def definir_variable_cantidad_creditos_por_cuatrimestre(arch, parametros): arch.write("#CREDi: Cantidad de creditos al final del cuatrimestre i" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): variable = "CRED{}".format(get_str_cuatrimestre(cuatrimestre)) arch.write("{} = LpVariable(name='{}', lowBound=0, upBound={}, cat='Integer')".format(variable, variable, INFINITO) + ENTER) arch.write(ENTER + ENTER)
def definir_variable_materia_i_en_cuatri_j(arch, parametros): arch.write("#Y_i_j: La materia con id i se realiza en el cuatrimestre j" + ENTER + ENTER) for id_materia in parametros.plan: for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): variable = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(cuatrimestre)) arch.write("{} = LpVariable(name='{}', cat='Binary')".format(variable, variable) + ENTER) arch.write(ENTER + ENTER)
def definir_variable_materia_trabajo_final_en_cuatri_j(arch, parametros): arch.write("#Y_TP_FINAL_i_j_k: La materia con id i y codigo j se realiza en el cuatrimestre k" + ENTER + ENTER) for materia in parametros.materia_trabajo_final: for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): variable = "Y_TP_FINAL_{}_{}_{}".format(materia.id_materia, materia.codigo, get_str_cuatrimestre(cuatrimestre)) arch.write("{} = LpVariable(name='{}', cat='Binary')".format(variable, variable) + ENTER) arch.write(ENTER + ENTER)
def generar_restriccion_creditos_minimos_ya_obtenidos_para_cursar( arch, parametros): arch.write( "# Restricciones sobre aquellas materias que requieren creditos minimos para poder cursar" + ENTER + ENTER) for id_materia in parametros.plan: materia = parametros.materias[id_materia] if materia.creditos_minimos_aprobados == 0: continue for i in range(1, parametros.max_cuatrimestres + 1): creditos = "CRED{}".format(get_str_cuatrimestre( i - 1)) if i > 1 else parametros.creditos_preacumulados var_Y = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(i)) arch.write("prob += ({}*{} <= {})".format( materia.creditos_minimos_aprobados, var_Y, creditos) + ENTER) arch.write(ENTER) arch.write(ENTER)
def guardar_variables_horarios_cada_curso_por_materia(arch, parametros): horarios = parametros.horarios for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for materia in horarios: for curso in horarios[materia]: variable = "H_{}_{}_{}".format(materia, curso.id_curso, get_str_cuatrimestre(cuatrimestre)) arch.write(LINEA_GUARDAR.format(variable, '{}', variable) + ENTER)
def generar_restriccion_la_materia_no_puede_cursarse_en_mas_de_un_curso( arch, parametros): arch.write( "# La materia no puede cursarse en mas de un curso en el cuatrimestre" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for id_materia in parametros.horarios: ecuacion = "" for curso in parametros.horarios[id_materia]: ecuacion += "H_{}_{}_{} + ".format( id_materia, curso.id_curso, get_str_cuatrimestre(cuatrimestre)) Y = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(cuatrimestre)) arch.write("prob += ({} <= {})".format(Y, ecuacion[:-3]) + ENTER) arch.write("prob += ({} >= {})".format(Y, ecuacion[:-3]) + ENTER) arch.write(ENTER)
def generar_restriccion_creditos_minimos_ya_obtenidos_para_cursar_el_trabajo_final( arch, parametros): arch.write("# Restriccion de creditos minimos para el trabajo final" + ENTER + ENTER) for materia in parametros.materia_trabajo_final: if materia.creditos_minimos_aprobados == 0: continue for i in range(1, parametros.max_cuatrimestres + 1): creditos = "CRED{}".format(get_str_cuatrimestre( i - 1)) if i > 1 else parametros.creditos_preacumulados variable_Y = "Y_TP_FINAL_{}_{}_{}".format( materia.id_materia, materia.codigo, get_str_cuatrimestre(get_str_cuatrimestre(i))) arch.write("prob += ({}*{} <= {})".format( materia.creditos_minimos_aprobados, variable_Y, creditos) + ENTER) arch.write(ENTER) arch.write(ENTER)
def definir_variables_horarios_cada_curso_por_materia(arch, parametros): arch.write( "#H_{id_materia i}_{id curso j}_{cuatrimestre k}: La materia i se cursa en el curso j en el cuatrimestre k" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for id_materia in parametros.horarios: for curso in parametros.horarios[id_materia]: variable = "H_{}_{}_{}".format(id_materia, curso.id_curso, get_str_cuatrimestre(cuatrimestre)) arch.write("{} = LpVariable(name='{}', cat='Binary')".format(variable, variable) + ENTER) arch.write(ENTER + ENTER)
def definir_variables_dias_y_franja_por_cuatrimestre(arch, parametros): arch.write( "#{Dia i}_{Franja j}_{cuatrimestre k}: El dia i (LUNES; MARTES, etc) en la franja horaria j en el cuatrimestre k se esta cursando" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for dia in parametros.dias: for franja in range(parametros.franja_minima, parametros.franja_maxima + 1): variable = "{}_{}_{}".format(dia, franja, get_str_cuatrimestre(cuatrimestre)) arch.write("{} = LpVariable(name='{}', cat='Binary')".format(variable, variable) + ENTER) arch.write(ENTER + ENTER)
def guardar_variables_horario_de_la_materia_en_dia_y_cuatrimestre(arch, parametros): horarios = parametros.horarios for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for materia in horarios: for curso in horarios[materia]: for c_horario in curso.horarios: if not es_horario_valido_para_el_cuatrimestre(parametros, curso, cuatrimestre): continue dia = c_horario.dia franjas = c_horario.get_franjas_utilizadas() for franja in franjas: variable = "R_{}_{}_{}_{}_{}".format(materia, curso.id_curso, dia, franja, get_str_cuatrimestre(cuatrimestre)) arch.write(LINEA_GUARDAR.format(variable, '{}', variable) + ENTER)
def generar_restriccion_maxima_cantidad_horas_cursada(arch, parametros): arch.write( "# Maxima cantidad de horas semanales de cursada (se calcula una semana" " por cuatrimestre)" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): ecuacion = "prob += (" for id_materia in parametros.horarios: for curso in parametros.horarios[id_materia]: variable = "H_{}_{}_{}".format( id_materia, curso.id_curso, get_str_cuatrimestre(cuatrimestre)) ecuacion += "{}*{} + ".format(curso.medias_horas_cursada, variable) ecuacion = ecuacion[:-3] arch.write("{} <= {})".format(ecuacion, parametros.max_horas_cursada) + ENTER) arch.write(ENTER + ENTER)
def generar_restriccion_no_todos_los_cursos_se_dictan_ambos_cuatrimestres( arch, parametros): arch.write("# No todos los cursos se dictan ambos cuatrimestres" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for id_materia in parametros.horarios: for curso in parametros.horarios[id_materia]: if es_horario_valido_para_el_cuatrimestre( parametros, curso, cuatrimestre): continue variable = "H_{}_{}_{}".format( id_materia, curso.id_curso, get_str_cuatrimestre(cuatrimestre)) arch.write("prob += ({} <= 0)".format(variable) + ENTER) arch.write("prob += ({} >= 0)".format(variable) + ENTER) arch.write(ENTER)
def definir_variables_horario_de_la_materia_en_dia_y_cuatrimestre(arch, parametros): arch.write("#R_{id_materia}_{id curso}_{dia}_{franja}_{cuatrimestre}: " "El horario para la materia y curso en ese cuatrimestre esta habilitado" + ENTER + ENTER) for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for id_materia in parametros.horarios: for curso in parametros.horarios[id_materia]: for c_horario in curso.horarios: if not es_horario_valido_para_el_cuatrimestre(parametros, curso, cuatrimestre): continue dia = c_horario.dia franjas = c_horario.get_franjas_utilizadas() for franja in franjas: variable = "R_{}_{}_{}_{}_{}".format(id_materia, curso.id_curso, dia, franja, get_str_cuatrimestre(cuatrimestre)) arch.write("{} = LpVariable(name='{}', cat='Binary')".format(variable, variable) + ENTER) arch.write(ENTER + ENTER)
def generar_restriccion_materias_incompatibles(arch, parametros): arch.write("# Si una materia es incompatible con otra, solo puede " "cursarse una de ellas" + ENTER + ENTER) for id_materia in parametros.materias_incompatibles: incompatibles = parametros.materias_incompatibles[id_materia] + [ id_materia ] ecuacion = "prob += (" for id_incompatible in incompatibles: for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): variable = "Y_{}_{}".format(id_incompatible, get_str_cuatrimestre(cuatrimestre)) ecuacion += variable + " + " ecuacion = ecuacion[:-3] ecuacion += " <= 1)" arch.write(ecuacion + ENTER) arch.write(ENTER) arch.write(ENTER)
def generar_restriccion_el_trabajo_debe_cursarse_en_unico_cuatrimestre( arch, parametros): arch.write("# La El trabajo final debe cursar (cada una de sus partes) " "en un unico cuatrimestre. Ademas, es obligatorio" + ENTER + ENTER) for materia in parametros.materia_trabajo_final: ecuacion = "prob += (" for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): if cuatrimestre > 1: ecuacion += " + " variable = "Y_TP_FINAL_{}_{}_{}".format( materia.id_materia, materia.codigo, get_str_cuatrimestre(cuatrimestre)) ecuacion += variable arch.write(ecuacion + " <= 1)" + ENTER) arch.write(ecuacion + " >= 1)" + ENTER) arch.write(ENTER) arch.write(ENTER)
def generar_restriccion_valor_cuatrimestre_en_que_se_cursa_la_materia( arch, parametros): arch.write("# Numero de cuatrimestre en que es cursada la materia" + ENTER + ENTER) for id_materia in parametros.plan: ecuacion = "prob += (" for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): if cuatrimestre > 1: ecuacion += " + " variable = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(cuatrimestre)) ecuacion += "{}*{}".format(cuatrimestre, variable) variable_c_materia = "C{}".format(id_materia) ecuacion_complementaria = ecuacion ecuacion += "<= {})".format(variable_c_materia) ecuacion_complementaria += ">= {})".format(variable_c_materia) arch.write(ecuacion + ENTER) arch.write(ecuacion_complementaria + ENTER) arch.write(ENTER) arch.write(ENTER)
def generar_restriccion_creditos_minimos_por_tematica(arch, parametros): if not parametros.creditos_minimos_tematicas: return arch.write("#Se debe realizar un minimo de creditos de materias electivas" "con diferentes tematicas" + ENTER + ENTER) for tematica in parametros.creditos_minimos_tematicas: ecuacion = "prob += (" for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for id_materia in parametros.materias: materia = parametros.materias[id_materia] if materia.tipo == OBLIGATORIA or not tematica in materia.tematicas_principales: continue Y = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(cuatrimestre)) ecuacion += Y + "*" + str(materia.creditos) + " + " ecuacion = ecuacion[:-3] arch.write(ecuacion + " >= " + str(parametros.creditos_minimos_tematicas[tematica]) + ")" + ENTER + ENTER) arch.write(ENTER)
def generar_restriccion_valor_cuatrimestre_en_que_se_cursa_el_trabajo_final( arch, parametros): arch.write("# Numero de cuatrimestre en que son " "cursadas las partes del trabajo final" + ENTER + ENTER) for materia in parametros.materia_trabajo_final: ecuacion = "prob += (" for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): if cuatrimestre > 1: ecuacion += " + " variable = "Y_TP_FINAL_{}_{}_{}".format( materia.id_materia, materia.codigo, get_str_cuatrimestre(cuatrimestre)) ecuacion += "{}*{}".format(cuatrimestre, variable) variable_c_materia = "C_TP_FINAL_{}_{}".format(materia.id_materia, materia.codigo) ecuacion_complementaria = ecuacion ecuacion += "<= {})".format(variable_c_materia) ecuacion_complementaria += ">= {})".format(variable_c_materia) arch.write(ecuacion + ENTER) arch.write(ecuacion_complementaria + ENTER) arch.write(ENTER) arch.write(ENTER)
def generar_restriccion_la_materia_debe_cursarse_en_unico_cuatrimestre( arch, parametros): arch.write( "# La materia i se debe cursar en un unico cuatrimestre. Ademas, si es obligatoria, debe cursarse si o si." + ENTER + ENTER) for id_materia in parametros.materias: ecuacion = "prob += (" for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): if cuatrimestre > 1: ecuacion += " + " variable = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(cuatrimestre)) ecuacion += variable ecuacion_complementaria = ecuacion ecuacion += " <= 1)" ecuacion_complementaria += " >= 1)" if parametros.materias[id_materia].tipo == OBLIGATORIA: arch.write(ecuacion_complementaria + ENTER) arch.write(ecuacion + ENTER) arch.write(ENTER) arch.write(ENTER)
def guardar_variable_cantidad_creditos_por_cuatrimestre(arch, parametros): for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): variable = "CRED{}".format(get_str_cuatrimestre(cuatrimestre)) arch.write(LINEA_GUARDAR.format(variable, '{}', variable) + ENTER)
def guardar_variable_materia_i_en_cuatri_j(arch, parametros): for id_materia in parametros.plan: for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): variable = "Y_{}_{}".format(id_materia, get_str_cuatrimestre(cuatrimestre)) arch.write(LINEA_GUARDAR.format(variable, '{}', variable) + ENTER)
def guardar_variables_dias_y_franja_por_cuatrimestre(arch, parametros): for cuatrimestre in range(1, parametros.max_cuatrimestres + 1): for dia in parametros.dias: for franja in range(parametros.franja_minima, parametros.franja_maxima + 1): variable = "{}_{}_{}".format(dia, franja, get_str_cuatrimestre(cuatrimestre)) arch.write(LINEA_GUARDAR.format(variable, '{}', variable) + ENTER)