generator.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package schedule
  2. import (
  3. "fmt"
  4. "encoding/json"
  5. )
  6. func NewGenerator(data *Generator) *Generator {
  7. return &Generator{
  8. Day: data.Day,
  9. Debug: data.Debug,
  10. Groups: data.Groups,
  11. Teachers: data.Teachers,
  12. Cabinets: data.Cabinets,
  13. // Blocked: make(map[string]bool),
  14. Reserved: Reserved{
  15. Teachers: make(map[string][]bool),
  16. Cabinets: make(map[string][]bool),
  17. },
  18. }
  19. }
  20. func (gen *Generator) NewSchedule(group string) *Schedule {
  21. return &Schedule{
  22. Day: gen.Day,
  23. Group: group,
  24. Table: make([]Row, NUM_TABLES),
  25. }
  26. }
  27. func ReadGroups(filename string) map[string]*Group {
  28. var (
  29. groups = make(map[string]*Group)
  30. groupsList []GroupJSON
  31. )
  32. data := readFile(filename)
  33. err := json.Unmarshal([]byte(data), &groupsList)
  34. if err != nil {
  35. return nil
  36. }
  37. for _, gr := range groupsList {
  38. groups[gr.Name] = &Group{
  39. Name: gr.Name,
  40. Quantity: gr.Quantity,
  41. }
  42. groups[gr.Name].Subjects = make(map[string]*Subject)
  43. for _, sb := range gr.Subjects {
  44. if _, ok := groups[gr.Name].Subjects[sb.Name]; ok {
  45. groups[gr.Name].Subjects[sb.Name].Teacher2 = sb.Teacher
  46. continue
  47. }
  48. groups[gr.Name].Subjects[sb.Name] = &Subject{
  49. Name: sb.Name,
  50. Teacher: sb.Teacher,
  51. IsComputer: sb.IsComputer,
  52. SaveWeek: sb.Lessons.Week,
  53. Lessons: Lessons{
  54. Theory: sb.Lessons.Theory,
  55. Practice: Subgroup{
  56. A: sb.Lessons.Practice,
  57. B: sb.Lessons.Practice,
  58. },
  59. Week: Subgroup{
  60. A: sb.Lessons.Week,
  61. B: sb.Lessons.Week,
  62. },
  63. },
  64. }
  65. }
  66. }
  67. return groups
  68. }
  69. func ReadTeachers(filename string) map[string]*Teacher {
  70. var (
  71. teachers = make(map[string]*Teacher)
  72. teachersList []Teacher
  73. )
  74. data := readFile(filename)
  75. err := json.Unmarshal([]byte(data), &teachersList)
  76. if err != nil {
  77. return nil
  78. }
  79. for _, tc := range teachersList {
  80. teachers[tc.Name] = &Teacher{
  81. Name: tc.Name,
  82. Cabinets: tc.Cabinets,
  83. }
  84. }
  85. return teachers
  86. }
  87. func ReadCabinets(filename string) map[string]*Cabinet {
  88. var (
  89. cabinets = make(map[string]*Cabinet)
  90. cabinetsList []Cabinet
  91. )
  92. data := readFile(filename)
  93. err := json.Unmarshal([]byte(data), &cabinetsList)
  94. if err != nil {
  95. return nil
  96. }
  97. for _, cb := range cabinetsList {
  98. cabinets[cb.Name] = &Cabinet{
  99. Name: cb.Name,
  100. IsComputer: cb.IsComputer,
  101. }
  102. }
  103. return cabinets
  104. }
  105. func (gen *Generator) Generate(template [][]*Schedule) []*Schedule {
  106. var (
  107. list []*Schedule
  108. templt []*Schedule
  109. groups = getGroups(gen.Groups)
  110. )
  111. if template == nil {
  112. templt = nil
  113. } else {
  114. templt = template[gen.Day]
  115. }
  116. for _, group := range groups {
  117. var (
  118. schedule = gen.NewSchedule(group.Name)
  119. subjects = getSubjects(group.Subjects)
  120. countLessons = new(Subgroup)
  121. )
  122. if gen.Day == SUNDAY {
  123. list = append(list, schedule)
  124. for _, subject := range subjects {
  125. saved := gen.Groups[group.Name].Subjects[subject.Name].SaveWeek
  126. gen.Groups[group.Name].Subjects[subject.Name].Lessons.Week.A = saved
  127. gen.Groups[group.Name].Subjects[subject.Name].Lessons.Week.B = saved
  128. }
  129. continue
  130. }
  131. for _, subject := range subjects {
  132. switch {
  133. case gen.haveTheoreticalLessons(subject):
  134. if gen.Debug {
  135. fmt.Println(group.Name, subject.Name, ": not splited THEORETICAL;")
  136. }
  137. gen.tryGenerate(ALL, THEORETICAL, group, subject, schedule, countLessons, templt)
  138. // Практические пары начинаются только после завершения всех теоретических.
  139. default:
  140. // Если подгруппа неделимая, тогда провести практику в виде полной пары.
  141. // Иначе разделить практику на две подгруппы.
  142. if !gen.withSubgroups(group.Name) {
  143. if gen.Debug {
  144. fmt.Println(group.Name, subject.Name, ": not splited PRACTICAL;")
  145. }
  146. gen.tryGenerate(ALL, PRACTICAL, group, subject, schedule, countLessons, templt)
  147. } else {
  148. switch RandSubgroup() {
  149. case A:
  150. if gen.Debug {
  151. fmt.Println(group.Name, subject.Name, ": splited (A -> B);")
  152. }
  153. gen.tryGenerate(A, PRACTICAL, group, subject, schedule, countLessons, templt)
  154. gen.tryGenerate(B, PRACTICAL, group, subject, schedule, countLessons, templt)
  155. case B:
  156. if gen.Debug {
  157. fmt.Println(group.Name, subject.Name, ": splited (B -> A);")
  158. }
  159. gen.tryGenerate(B, PRACTICAL, group, subject, schedule, countLessons, templt)
  160. gen.tryGenerate(A, PRACTICAL, group, subject, schedule, countLessons, templt)
  161. }
  162. }
  163. }
  164. }
  165. list = append(list, schedule)
  166. }
  167. gen.Reserved.Teachers = make(map[string][]bool)
  168. gen.Reserved.Cabinets = make(map[string][]bool)
  169. gen.Day = (gen.Day + 1) % 7
  170. return sortSchedule(list)
  171. }
  172. func RandSubgroup() SubgroupType {
  173. return SubgroupType(random(0, 1))
  174. }
  175. func Load(filename string) *Generator {
  176. var generator = new(Generator)
  177. jsonData := readFile(filename)
  178. err := json.Unmarshal([]byte(jsonData), generator)
  179. if err != nil {
  180. return nil
  181. }
  182. return generator
  183. }
  184. func (gen *Generator) Dump(filename string) error {
  185. return writeJSON(filename, gen)
  186. }