import string
def outputZimplStr(orig):
cnt = 1
outL = []
for s in orig:
outL.append("<%02i> \"%s\"" % (cnt, s))
cnt += 1
return string.join(outL, ", ")
def outputZimplInt(orig):
cnt = 1
outL = []
for i in orig:
outL.append("<%02i> %i" % (cnt, i))
cnt += 1
return string.join(outL, ", ")
def outputZimplSet(orig):
cnt = 1
outL = []
for l in orig:
for i in range(0, len(l)):
outL.append("<%02i,%i> %s" % (cnt, i + 1, str(l[i])))
cnt += 1
return string.join(outL, ", ")
def outputZimplSetCard(orig):
cnt = 1
outL = []
for l in orig:
outL.append("<%02i> %i" % (cnt, len(l)))
cnt += 1
return string.join(outL, ", ")
def check_and_gen_udine(ps):
toSave = None
penalty = 0
if ps[0] == 1 and ps[1] == -1: penalty += 1
if ps[-1] == 1 and ps[-2] == -1: penalty += 1
for i in range(0, len(ps) - 2):
if ps[i + 0] == -1 and ps[i + 1] == 1 and ps[i + 2] == -1: penalty += 1
if penalty > 0:
positive = filter(lambda x: x > 0, ps)
toSave = [penalty] + ps + [sum(positive) - 1]
return toSave
def addUdinePatternPenalisation(outfilename, variant = 4):
out = open(outfilename, "a")
vals = [-1, 1]
patterns = []
for p1 in vals:
for p2 in vals:
for p3 in vals:
for p4 in vals:
toSave = None
if variant == 5:
for p5 in vals:
toSave = check_and_gen_udine([p1, p2, p3, p4, p5])
if toSave != None: patterns.append(toSave)
toSave = None
else:
toSave = check_and_gen_udine([p1, p2, p3, p4])
if toSave != None: patterns.append(toSave)
patternsText = ["<" + string.join(map(str, pattern), ", ") + ">" for pattern in patterns]
out.write("set BannedCurriculumPatterns := { \n" + string.join(patternsText, ", \n") + "};\n\n")
out.close()
def outputZimpl(infilename, modelname = "sparse14"):
outfilename = infilename + "." + modelname + ".zpl"
lines = open(infilename, "r").readlines()
info = {'HeadLen' : 6}
currentLine = 1
for infoline in lines[currentLine : currentLine + info['HeadLen']]:
f = infoline.split(": ")
if (len(f) != 2): continue
info[f[0]] = int(f[1])
output = ""
output += "param nbPeriodsPerDay := %i;\n" % info['Periods_per_day']
output += "param nbDaySingletonChecks := %i;\n" % info['Periods_per_day']
output += "param nbRooms := %i;\n" % (info['Rooms'])
output += "param nbDays := %i;\n" % (info['Days'])
output += "param nbCurricula := %i;\n" % (info['Curricula'])
output += "param nbCourses := %i;\n" % (info['Courses'])
output += "param nbPeriods := nbDays * nbPeriodsPerDay;\n"
output += "param nbMaxListCourses := 10;\n"
output += "param nbMaxListPeriods := 50;\n"
output += "param nbMaxEventsPerCourse := 6;\n"
output += """
set Periods := { 1 .. nbPeriods };
set Rooms := { 1 .. nbRooms };
set Courses := { 1 .. nbCourses };
set Curricula := { 1 .. nbCurricula };
set Days := { 1 .. nbDays };
set ListCourses := { 1 .. nbMaxListCourses };
set ListPeriods := { 1 .. nbMaxListPeriods };
set PeriodsPerDay := { 1 .. nbPeriodsPerDay };
set DaySingletonChecks := { 1 .. nbDaySingletonChecks };\n\n"""
curriculaTemp = []
currentLine += info['HeadLen'] + 2 + info['Courses'] + 2 + info['Rooms'] + 2
for curriculaLine in lines[currentLine : currentLine + info['Curricula']]:
f = curriculaLine.split()
if (len(f) < 3): continue
if (len(f) != int(f[1]) + 2): continue
curriculaTemp.append(f[2:])
deprecatedTemp = {}
currentLine = 3 + info['HeadLen'] + 2 + info['Courses'] + 2 + info['Rooms'] + info['Curricula'] + 2
for deprecatedLine in lines[currentLine : currentLine + info['Constraints']]:
f = deprecatedLine.split()
if (len(f) < 3): continue
period = int(f[1]) * info['Periods_per_day'] + int(f[2]) + 1
if not deprecatedTemp.has_key(f[0]): deprecatedTemp[f[0]] = []
deprecatedTemp[f[0]].append(str(period))
output += "param RoomHasCapacity[Rooms] := ";
outputTemp = []
currentLine = 1 + info['HeadLen'] + 2 + info['Courses'] + 2
roomCnt = 1
for roomLine in lines[currentLine : currentLine + info['Rooms']]:
f = roomLine.split()
if (len(f) != 2): continue
outputTemp.append(("<%02i> " % roomCnt) + f[1])
roomCnt += 1
output += string.join(outputTemp, ", ")
output += ";\n\n";
outputTemp = []
coursesTemp = {}
TeacherToEvents = {}
TeacherToCourses = {}
currentLine = 1 + info['HeadLen'] + 2
courseId = 1
cTeachersList = []
cStudentsList = []
cNamesList = []
cCurriculaList = []
CurriculaToEvents = [0 for i in range(1, info['Curricula'] + 2)]
TeacherToEventsCount = {}
CurriculaToCourses = [[] for i in range(1, info['Curricula'] + 2)]
CoursesToEvents = [[] for i in range(1, info['Courses'] + 2)]
courseNames = []
courseTeachers = []
courseLectures = []
courseMindays = []
courseStudents = []
courseInavail = []
for courseLine in lines[currentLine : currentLine + info['Courses']]:
f = courseLine.split()
if (len(f) != 5): continue
courseNames.append(f[0])
courseTeachers.append(f[1])
courseLectures.append(int(f[4]))
courseMindays.append(int(f[2]))
courseStudents.append(int(f[3]))
inCurricula = []
for i in range(0, len(curriculaTemp)):
if f[0] in curriculaTemp[i]: inCurricula.append(str(i + 1))
(cName, cTeacher, cStudents, cSessions, cMindays, cCurricula) = (f[0], f[1], int(f[4]), int(f[2]), int(f[3]), inCurricula)
if not TeacherToEvents.has_key(f[1]): TeacherToEvents[f[1]] = []
if not TeacherToCourses.has_key(f[1]): TeacherToCourses[f[1]] = []
if deprecatedTemp.has_key(f[0]): courseInavail.append(deprecatedTemp[f[0]])
else: courseInavail.append([])
TeacherToCourses[cTeacher].append(courseId)
for cu in cCurricula:
CurriculaToCourses[int(cu)].append(courseId)
CurriculaToEvents[int(cu)] += cSessions
if not TeacherToEventsCount.has_key(cTeacher): TeacherToEventsCount[cTeacher] = 0
TeacherToEventsCount[cTeacher] += cSessions
courseId += 1
currentLine = 1 + info['HeadLen'] + 2 + info['Courses'] + 2 + info['Rooms'] + 2
for curriculaLine in lines[currentLine : currentLine + info['Curricula']]:
f = curriculaLine.split()
if (len(f) < 3): continue
if (len(f) != int(f[1]) + 2): continue
curriculaTemp.append(f[2:])
output += "param CourseHasName[Courses] := " + outputZimplStr(courseNames) + ";\n\n"
output += "param CourseHasTeacher[Courses] := " + outputZimplStr(courseTeachers) + ";\n\n"
output += "param CourseHasStudents[Courses] := " + outputZimplInt(courseLectures) + ";\n\n"
output += "param CourseHasEvents[Courses] := " + outputZimplInt(courseMindays) + ";\n\n"
output += "param CourseHasMindays[Courses] := " + outputZimplInt(courseStudents) + ";\n\n"
output += "param CourseHasDeprecatedPeriodsCount[Courses] := " + outputZimplSetCard(courseInavail) + ";\n\n"
output += "param CourseHasDeprecatedPeriods[Courses * ListPeriods] := " + outputZimplSet(courseInavail) + ";\n\n"
output += "param CurriculumHasCoursesCount[Curricula] := " + outputZimplSetCard(CurriculaToCourses[1:]) + ";\n\n"
output += "param CurriculumHasCourses[Curricula * ListCourses] := " + outputZimplSet(CurriculaToCourses[1:]) + ";\n\n"
CurriculumHasCoursesCount = [sum(map(lambda x: 1, x)) for x in CurriculaToCourses[1:]]
output += "param CurriculumHasEventsCount[Curricula] := " + outputZimplInt(CurriculaToEvents[1:]) + ";\n\n"
output += "param nbTeachers := %i;\n" % (len(TeacherToEvents.keys()))
output += "set Teachers := { 1 .. nbTeachers };\n\n"
teachersKeys = TeacherToEvents.keys()
TeacherHasCourses = [TeacherToCourses[x] for x in teachersKeys]
TeacherHasEventsCount = [TeacherToEventsCount[key] for key in teachersKeys]
output += "param TeacherHasCoursesCount[Teachers] := " + outputZimplSetCard(TeacherHasCourses) + ";\n\n"
output += "param TeacherHasCourses[Teachers * ListCourses] := " + outputZimplSet(TeacherHasCourses) + ";\n\n"
output += "param TeacherHasEventsCount[Teachers] := " + outputZimplInt(TeacherHasEventsCount) + ";\n\n"
cnt = 1
outputNamed = []
outputPlain = []
for day in range(0, info['Days']):
strNum = map(str, range(day * info['Periods_per_day'] + 1, (day + 1) * info['Periods_per_day'] + 1))
outputNamed.append(string.join([str(day + 1)]+ strNum, ", "))
outputPlain.append(strNum)
output += "param HasPeriods[Days * PeriodsPerDay] := ";
output += outputZimplSet(outputPlain)
output += ";\n\n";
output += "set HasNamedPeriods := { ";
output += " <" + string.join(outputNamed, ">, <") + "> "
output += "};\n";
modelfilename = modelname + ".%i.zpl" % info['Periods_per_day']
model = open(modelfilename).read()
outfile = open(outfilename, "w")
outfile.write(output)
outfile.close()
addUdinePatternPenalisation(outfilename, info['Periods_per_day'])
outfile = open(outfilename, "a")
outfile.write(model)
outfile.close()