|
@@ -4,7 +4,7 @@ import (
|
|
|
"os"
|
|
|
"sort"
|
|
|
"time"
|
|
|
- "errors"
|
|
|
+ // "errors"
|
|
|
"math/rand"
|
|
|
"encoding/json"
|
|
|
)
|
|
@@ -22,7 +22,20 @@ func (gen *Generator) tryGenerate(
|
|
|
countl *Subgroup,
|
|
|
template []*Schedule,
|
|
|
) {
|
|
|
- flag := false
|
|
|
+ var (
|
|
|
+ indexGroup = -1
|
|
|
+ flag = false
|
|
|
+ )
|
|
|
+ if template != nil {
|
|
|
+ for i, sch := range template {
|
|
|
+ if sch.Group == group.Name {
|
|
|
+ indexGroup = i
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if indexGroup == -1 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
startAgain:
|
|
|
nextLesson: for lesson := uint(0); lesson < NUM_TABLES; lesson++ {
|
|
|
// Если лимит пар на день окончен, тогда прекратить ставить пары группе.
|
|
@@ -42,7 +55,7 @@ startAgain:
|
|
|
|
|
|
// Если учитель заблокирован (не может присутствовать на занятиях) или
|
|
|
// лимит пар на текущую неделю для предмета завершён, тогда пропустить этот предмет.
|
|
|
- if gen.inBlocked(subject.Teacher) || gen.notHaveWeekLessons(subgroup, subject) {
|
|
|
+ if gen.notHaveWeekLessons(subgroup, subject) { // gen.inBlocked(subject.Teacher) ||
|
|
|
break nextLesson
|
|
|
}
|
|
|
|
|
@@ -167,22 +180,16 @@ tryAfter:
|
|
|
}
|
|
|
|
|
|
// Если существует шаблон расписания, тогда придерживаться его структуры.
|
|
|
- if template != nil {
|
|
|
- for _, sch := range template {
|
|
|
- if sch.Group == group.Name {
|
|
|
- if sch.Table[lesson].Subject[A] == "" && sch.Table[lesson].Subject[B] == "" {
|
|
|
- if (gen.cellIsReserved(A, schedule, lesson) && !gen.cellIsReserved(B, schedule, lesson)) ||
|
|
|
- (gen.cellIsReserved(B, schedule, lesson) && !gen.cellIsReserved(A, schedule, lesson)) {
|
|
|
- break
|
|
|
- }
|
|
|
- lesson = savedLesson
|
|
|
- continue nextLesson
|
|
|
- }
|
|
|
- break
|
|
|
- }
|
|
|
+ if template != nil && template[indexGroup].Table[lesson].Subject[A] == "" && template[indexGroup].Table[lesson].Subject[B] == "" {
|
|
|
+ if (gen.cellIsReserved(A, schedule, lesson) && !gen.cellIsReserved(B, schedule, lesson)) ||
|
|
|
+ (gen.cellIsReserved(B, schedule, lesson) && !gen.cellIsReserved(A, schedule, lesson)) {
|
|
|
+ goto passTemplate
|
|
|
}
|
|
|
+ lesson = savedLesson
|
|
|
+ continue nextLesson
|
|
|
}
|
|
|
|
|
|
+passTemplate:
|
|
|
// Полный день - максимум 7 пар.
|
|
|
// lesson начинается с нуля!
|
|
|
if (gen.Day != WEDNESDAY && gen.Day != SATURDAY) && lesson >= 7 {
|
|
@@ -213,7 +220,7 @@ tryAfter:
|
|
|
// в это же время, тогда пропустить проверку пустых окон.
|
|
|
if gen.cellIsReserved(A, schedule, lesson) && A != subgroup ||
|
|
|
gen.cellIsReserved(B, schedule, lesson) && B != subgroup {
|
|
|
- goto passcheck
|
|
|
+ goto passCheck
|
|
|
}
|
|
|
// Если стоит полная пара, а за ней идёт подгруппа неравная проверяемой, тогда
|
|
|
// прекратить ставить пары у проверяемой подгруппы.
|
|
@@ -230,7 +237,7 @@ tryAfter:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-passcheck:
|
|
|
+passCheck:
|
|
|
// [ III ] Третья проверка.
|
|
|
// Если нет возможности добавить новые пары без создания окон, тогда не ставить пары.
|
|
|
if lesson > 1 {
|
|
@@ -256,24 +263,24 @@ passcheck:
|
|
|
|
|
|
switch subgroup {
|
|
|
case A:
|
|
|
- gen.Groups[group.Name].Subjects[subject.Name].WeekLessons.A -= 1
|
|
|
- gen.Groups[group.Name].Subjects[subject.Name].Practice.A -= 1
|
|
|
+ gen.Groups[group.Name].Subjects[subject.Name].Lessons.Week.A -= 1
|
|
|
+ gen.Groups[group.Name].Subjects[subject.Name].Lessons.Practice.A -= 1
|
|
|
countl.A += 1
|
|
|
case B:
|
|
|
- gen.Groups[group.Name].Subjects[subject.Name].WeekLessons.B -= 1
|
|
|
- gen.Groups[group.Name].Subjects[subject.Name].Practice.B -= 1
|
|
|
+ gen.Groups[group.Name].Subjects[subject.Name].Lessons.Week.B -= 1
|
|
|
+ gen.Groups[group.Name].Subjects[subject.Name].Lessons.Practice.B -= 1
|
|
|
countl.B += 1
|
|
|
case ALL:
|
|
|
- gen.Groups[group.Name].Subjects[subject.Name].WeekLessons.A -= 1
|
|
|
- gen.Groups[group.Name].Subjects[subject.Name].WeekLessons.B -= 1
|
|
|
+ gen.Groups[group.Name].Subjects[subject.Name].Lessons.Week.A -= 1
|
|
|
+ gen.Groups[group.Name].Subjects[subject.Name].Lessons.Week.B -= 1
|
|
|
countl.A += 1
|
|
|
countl.B += 1
|
|
|
switch subjtype {
|
|
|
case THEORETICAL:
|
|
|
- gen.Groups[group.Name].Subjects[subject.Name].Theory -= 1
|
|
|
+ gen.Groups[group.Name].Subjects[subject.Name].Lessons.Theory -= 1
|
|
|
case PRACTICAL:
|
|
|
- gen.Groups[group.Name].Subjects[subject.Name].Practice.A -= 1
|
|
|
- gen.Groups[group.Name].Subjects[subject.Name].Practice.B -= 1
|
|
|
+ gen.Groups[group.Name].Subjects[subject.Name].Lessons.Practice.A -= 1
|
|
|
+ gen.Groups[group.Name].Subjects[subject.Name].Lessons.Practice.B -= 1
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -338,20 +345,20 @@ func (gen *Generator) withSubgroups(group string) bool {
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
-func (gen *Generator) blockTeacher(teacher string) error {
|
|
|
- if !gen.inTeachers(teacher) {
|
|
|
- return errors.New("teacher undefined")
|
|
|
- }
|
|
|
- gen.Blocked[teacher] = true
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func (gen *Generator) inBlocked(teacher string) bool {
|
|
|
- if _, ok := gen.Blocked[teacher]; !ok {
|
|
|
- return false
|
|
|
- }
|
|
|
- return true
|
|
|
-}
|
|
|
+// func (gen *Generator) blockTeacher(teacher string) error {
|
|
|
+// if !gen.inTeachers(teacher) {
|
|
|
+// return errors.New("teacher undefined")
|
|
|
+// }
|
|
|
+// gen.Blocked[teacher] = true
|
|
|
+// return nil
|
|
|
+// }
|
|
|
+
|
|
|
+// func (gen *Generator) inBlocked(teacher string) bool {
|
|
|
+// if _, ok := gen.Blocked[teacher]; !ok {
|
|
|
+// return false
|
|
|
+// }
|
|
|
+// return true
|
|
|
+// }
|
|
|
|
|
|
func (gen *Generator) inGroups(group string) bool {
|
|
|
if _, ok := gen.Groups[group]; !ok {
|
|
@@ -367,13 +374,13 @@ func (gen *Generator) inTeachers(teacher string) bool {
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
-func (gen *Generator) unblockTeacher(teacher string) error {
|
|
|
- if !gen.inBlocked(teacher) {
|
|
|
- return errors.New("teacher undefined")
|
|
|
- }
|
|
|
- delete(gen.Blocked, teacher)
|
|
|
- return nil
|
|
|
-}
|
|
|
+// func (gen *Generator) unblockTeacher(teacher string) error {
|
|
|
+// if !gen.inBlocked(teacher) {
|
|
|
+// return errors.New("teacher undefined")
|
|
|
+// }
|
|
|
+// delete(gen.Blocked, teacher)
|
|
|
+// return nil
|
|
|
+// }
|
|
|
|
|
|
func packJSON(data interface{}) []byte {
|
|
|
jsonData, err := json.MarshalIndent(data, "", "\t")
|
|
@@ -457,10 +464,11 @@ func (gen *Generator) cellIsReserved(subgroup SubgroupType, schedule *Schedule,
|
|
|
}
|
|
|
|
|
|
func (gen *Generator) cabinetIsReserved(subgroup SubgroupType, subject *Subject, teacher string, lesson uint, cabinet *string) bool {
|
|
|
- var result = true
|
|
|
if !gen.inTeachers(teacher) {
|
|
|
- return result
|
|
|
+ return true
|
|
|
}
|
|
|
+
|
|
|
+ // Основные кабинеты преподавателя.
|
|
|
for _, cab := range gen.Teachers[teacher].Cabinets {
|
|
|
gen.cabinetToReserved(cab.Name)
|
|
|
// Если это не компьютерный кабинет, а предмет предполагает практику в компьютерных кабинетах и идёт время практики,
|
|
@@ -476,7 +484,25 @@ func (gen *Generator) cabinetIsReserved(subgroup SubgroupType, subject *Subject,
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
- return result
|
|
|
+
|
|
|
+ // Все другие кабинеты. Могут быть использованы в случае, если все основные кабинеты преподавателя были заняты.
|
|
|
+ for _, cab := range gen.Cabinets {
|
|
|
+ gen.cabinetToReserved(cab.Name)
|
|
|
+ // Если это не компьютерный кабинет, а предмет предполагает практику в компьютерных кабинетах и идёт время практики,
|
|
|
+ // тогда посмотреть другой кабинет преподавателя.
|
|
|
+ if subject.IsComputer && !cab.IsComputer &&
|
|
|
+ gen.havePracticalLessons(subgroup, subject) &&
|
|
|
+ !gen.haveTheoreticalLessons(subject) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ // Если кабинет не зарезирвирован, тогда занять кабинет.
|
|
|
+ if _, ok := gen.Reserved.Cabinets[cab.Name]; ok && !gen.Reserved.Cabinets[cab.Name][lesson] {
|
|
|
+ *cabinet = cab.Name
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true
|
|
|
}
|
|
|
|
|
|
func (gen *Generator) teacherIsReserved(teacher string, lesson uint) bool {
|
|
@@ -504,15 +530,15 @@ func (gen *Generator) cabinetToReserved(cabnum string) {
|
|
|
func (gen *Generator) notHaveWeekLessons(subgroup SubgroupType, subject *Subject) bool {
|
|
|
switch subgroup {
|
|
|
case A:
|
|
|
- if subject.WeekLessons.A == 0 {
|
|
|
+ if subject.Lessons.Week.A == 0 {
|
|
|
return true
|
|
|
}
|
|
|
case B:
|
|
|
- if subject.WeekLessons.B == 0 {
|
|
|
+ if subject.Lessons.Week.B == 0 {
|
|
|
return true
|
|
|
}
|
|
|
case ALL:
|
|
|
- if subject.WeekLessons.A == 0 && subject.WeekLessons.B == 0 {
|
|
|
+ if subject.Lessons.Week.A == 0 && subject.Lessons.Week.B == 0 {
|
|
|
return true
|
|
|
}
|
|
|
}
|
|
@@ -520,7 +546,7 @@ func (gen *Generator) notHaveWeekLessons(subgroup SubgroupType, subject *Subject
|
|
|
}
|
|
|
|
|
|
func (gen *Generator) haveTheoreticalLessons(subject *Subject) bool {
|
|
|
- if subject.Theory == 0 {
|
|
|
+ if subject.Lessons.Theory == 0 {
|
|
|
return false
|
|
|
}
|
|
|
return true
|
|
@@ -529,15 +555,15 @@ func (gen *Generator) haveTheoreticalLessons(subject *Subject) bool {
|
|
|
func (gen *Generator) havePracticalLessons(subgroup SubgroupType, subject *Subject) bool {
|
|
|
switch subgroup {
|
|
|
case A:
|
|
|
- if subject.Practice.A == 0 {
|
|
|
+ if subject.Lessons.Practice.A == 0 {
|
|
|
return false
|
|
|
}
|
|
|
case B:
|
|
|
- if subject.Practice.B == 0 {
|
|
|
+ if subject.Lessons.Practice.B == 0 {
|
|
|
return false
|
|
|
}
|
|
|
case ALL:
|
|
|
- if subject.Practice.A == 0 && subject.Practice.B == 0 {
|
|
|
+ if subject.Lessons.Practice.A == 0 && subject.Lessons.Practice.B == 0 {
|
|
|
return false
|
|
|
}
|
|
|
}
|