mirror of
https://github.com/sabazadam/Se302.git
synced 2025-12-31 12:21:22 +00:00
Reworked Schedule Generating Algorithm
This commit is contained in:
@@ -1,59 +1,89 @@
|
|||||||
CourseCode_01
|
CourseCode_01
|
||||||
['Std_ID_170', 'Std_ID_077', 'Std_ID_097', 'Std_ID_202', 'Std_ID_080', 'Std_ID_126', 'Std_ID_112', 'Std_ID_175', 'Std_ID_180', 'Std_ID_139', 'Std_ID_181', 'Std_ID_222', 'Std_ID_243', 'Std_ID_167', 'Std_ID_136', 'Std_ID_021', 'Std_ID_041', 'Std_ID_231', 'Std_ID_062', 'Std_ID_138', 'Std_ID_236', 'Std_ID_221', 'Std_ID_006', 'Std_ID_135', 'Std_ID_209', 'Std_ID_239', 'Std_ID_043', 'Std_ID_182', 'Std_ID_246', 'Std_ID_083', 'Std_ID_056', 'Std_ID_047', 'Std_ID_193', 'Std_ID_107', 'Std_ID_216', 'Std_ID_005', 'Std_ID_096', 'Std_ID_140', 'Std_ID_233', 'Std_ID_168']
|
['Std_ID_001', 'Std_ID_005', 'Std_ID_009', 'Std_ID_013', 'Std_ID_017', 'Std_ID_021', 'Std_ID_025', 'Std_ID_029', 'Std_ID_033', 'Std_ID_037', 'Std_ID_041', 'Std_ID_045', 'Std_ID_049', 'Std_ID_053', 'Std_ID_057', 'Std_ID_061', 'Std_ID_065', 'Std_ID_069', 'Std_ID_073', 'Std_ID_077', 'Std_ID_081', 'Std_ID_085', 'Std_ID_089', 'Std_ID_093', 'Std_ID_097', 'Std_ID_101', 'Std_ID_105', 'Std_ID_109', 'Std_ID_113', 'Std_ID_117', 'Std_ID_121', 'Std_ID_125', 'Std_ID_400', 'Std_ID_405', 'Std_ID_410']
|
||||||
|
|
||||||
CourseCode_02
|
CourseCode_02
|
||||||
['Std_ID_238', 'Std_ID_132', 'Std_ID_079', 'Std_ID_139', 'Std_ID_116', 'Std_ID_093', 'Std_ID_190', 'Std_ID_121', 'Std_ID_108', 'Std_ID_005', 'Std_ID_210', 'Std_ID_018', 'Std_ID_152', 'Std_ID_033', 'Std_ID_199', 'Std_ID_073', 'Std_ID_193', 'Std_ID_220', 'Std_ID_222', 'Std_ID_188', 'Std_ID_217', 'Std_ID_008', 'Std_ID_123', 'Std_ID_159', 'Std_ID_227', 'Std_ID_136', 'Std_ID_187', 'Std_ID_216', 'Std_ID_056', 'Std_ID_026', 'Std_ID_099', 'Std_ID_146', 'Std_ID_055', 'Std_ID_057', 'Std_ID_035', 'Std_ID_049', 'Std_ID_144', 'Std_ID_232', 'Std_ID_098', 'Std_ID_058']
|
['Std_ID_002', 'Std_ID_006', 'Std_ID_010', 'Std_ID_014', 'Std_ID_018', 'Std_ID_022', 'Std_ID_026', 'Std_ID_030', 'Std_ID_034', 'Std_ID_038', 'Std_ID_042', 'Std_ID_046', 'Std_ID_050', 'Std_ID_054', 'Std_ID_058', 'Std_ID_062', 'Std_ID_066', 'Std_ID_070', 'Std_ID_074', 'Std_ID_078', 'Std_ID_082', 'Std_ID_086', 'Std_ID_090', 'Std_ID_094', 'Std_ID_098', 'Std_ID_102', 'Std_ID_106', 'Std_ID_110', 'Std_ID_114', 'Std_ID_118', 'Std_ID_122', 'Std_ID_126', 'Std_ID_401', 'Std_ID_406', 'Std_ID_411']
|
||||||
|
|
||||||
CourseCode_03
|
CourseCode_03
|
||||||
['Std_ID_098', 'Std_ID_070', 'Std_ID_049', 'Std_ID_191', 'Std_ID_109', 'Std_ID_196', 'Std_ID_209', 'Std_ID_189', 'Std_ID_039', 'Std_ID_219', 'Std_ID_009', 'Std_ID_033', 'Std_ID_059', 'Std_ID_174', 'Std_ID_169', 'Std_ID_122', 'Std_ID_057', 'Std_ID_249', 'Std_ID_142', 'Std_ID_229', 'Std_ID_038', 'Std_ID_132', 'Std_ID_140', 'Std_ID_081', 'Std_ID_243', 'Std_ID_150', 'Std_ID_099', 'Std_ID_224', 'Std_ID_097', 'Std_ID_193', 'Std_ID_043', 'Std_ID_055', 'Std_ID_061', 'Std_ID_212', 'Std_ID_205', 'Std_ID_146', 'Std_ID_100', 'Std_ID_149', 'Std_ID_116', 'Std_ID_233']
|
['Std_ID_003', 'Std_ID_007', 'Std_ID_011', 'Std_ID_015', 'Std_ID_019', 'Std_ID_023', 'Std_ID_027', 'Std_ID_031', 'Std_ID_035', 'Std_ID_039', 'Std_ID_043', 'Std_ID_047', 'Std_ID_051', 'Std_ID_055', 'Std_ID_059', 'Std_ID_063', 'Std_ID_067', 'Std_ID_071', 'Std_ID_075', 'Std_ID_079', 'Std_ID_083', 'Std_ID_087', 'Std_ID_091', 'Std_ID_095', 'Std_ID_099', 'Std_ID_103', 'Std_ID_107', 'Std_ID_111', 'Std_ID_115', 'Std_ID_119', 'Std_ID_123', 'Std_ID_127', 'Std_ID_402', 'Std_ID_407', 'Std_ID_412']
|
||||||
|
|
||||||
CourseCode_04
|
CourseCode_04
|
||||||
['Std_ID_142', 'Std_ID_085', 'Std_ID_103', 'Std_ID_059', 'Std_ID_243', 'Std_ID_106', 'Std_ID_069', 'Std_ID_014', 'Std_ID_015', 'Std_ID_088', 'Std_ID_136', 'Std_ID_020', 'Std_ID_097', 'Std_ID_190', 'Std_ID_194', 'Std_ID_201', 'Std_ID_125', 'Std_ID_182', 'Std_ID_138', 'Std_ID_105', 'Std_ID_076', 'Std_ID_007', 'Std_ID_066', 'Std_ID_189', 'Std_ID_129', 'Std_ID_133', 'Std_ID_034', 'Std_ID_130', 'Std_ID_247', 'Std_ID_024', 'Std_ID_027', 'Std_ID_115', 'Std_ID_064', 'Std_ID_132', 'Std_ID_113', 'Std_ID_118', 'Std_ID_162', 'Std_ID_154', 'Std_ID_181', 'Std_ID_114']
|
['Std_ID_004', 'Std_ID_008', 'Std_ID_012', 'Std_ID_016', 'Std_ID_020', 'Std_ID_024', 'Std_ID_028', 'Std_ID_032', 'Std_ID_036', 'Std_ID_040', 'Std_ID_044', 'Std_ID_048', 'Std_ID_052', 'Std_ID_056', 'Std_ID_060', 'Std_ID_064', 'Std_ID_068', 'Std_ID_072', 'Std_ID_076', 'Std_ID_080', 'Std_ID_084', 'Std_ID_088', 'Std_ID_092', 'Std_ID_096', 'Std_ID_100', 'Std_ID_104', 'Std_ID_108', 'Std_ID_112', 'Std_ID_116', 'Std_ID_120', 'Std_ID_124', 'Std_ID_128', 'Std_ID_403', 'Std_ID_408', 'Std_ID_413']
|
||||||
|
|
||||||
CourseCode_05
|
CourseCode_05
|
||||||
['Std_ID_203', 'Std_ID_236', 'Std_ID_192', 'Std_ID_198', 'Std_ID_213', 'Std_ID_147', 'Std_ID_051', 'Std_ID_095', 'Std_ID_226', 'Std_ID_077', 'Std_ID_230', 'Std_ID_035', 'Std_ID_142', 'Std_ID_195', 'Std_ID_182', 'Std_ID_064', 'Std_ID_229', 'Std_ID_239', 'Std_ID_119', 'Std_ID_231', 'Std_ID_217', 'Std_ID_054', 'Std_ID_163', 'Std_ID_148', 'Std_ID_249', 'Std_ID_068', 'Std_ID_202', 'Std_ID_225', 'Std_ID_101', 'Std_ID_126', 'Std_ID_150', 'Std_ID_197', 'Std_ID_025', 'Std_ID_140', 'Std_ID_124', 'Std_ID_053', 'Std_ID_075', 'Std_ID_074', 'Std_ID_243', 'Std_ID_169']
|
['Std_ID_001', 'Std_ID_002', 'Std_ID_005', 'Std_ID_006', 'Std_ID_009', 'Std_ID_010', 'Std_ID_013', 'Std_ID_014', 'Std_ID_017', 'Std_ID_018', 'Std_ID_021', 'Std_ID_022', 'Std_ID_025', 'Std_ID_026', 'Std_ID_029', 'Std_ID_030', 'Std_ID_033', 'Std_ID_034', 'Std_ID_037', 'Std_ID_038', 'Std_ID_041', 'Std_ID_042', 'Std_ID_045', 'Std_ID_046', 'Std_ID_049', 'Std_ID_050', 'Std_ID_053', 'Std_ID_054', 'Std_ID_057', 'Std_ID_058', 'Std_ID_061', 'Std_ID_062', 'Std_ID_065', 'Std_ID_066', 'Std_ID_069', 'Std_ID_070', 'Std_ID_073', 'Std_ID_404', 'Std_ID_409', 'Std_ID_414']
|
||||||
|
|
||||||
CourseCode_06
|
CourseCode_06
|
||||||
['Std_ID_129', 'Std_ID_175', 'Std_ID_049', 'Std_ID_238', 'Std_ID_056', 'Std_ID_187', 'Std_ID_064', 'Std_ID_151', 'Std_ID_201', 'Std_ID_022', 'Std_ID_169', 'Std_ID_220', 'Std_ID_147', 'Std_ID_223', 'Std_ID_011', 'Std_ID_053', 'Std_ID_166', 'Std_ID_111', 'Std_ID_219', 'Std_ID_112', 'Std_ID_203', 'Std_ID_054', 'Std_ID_106', 'Std_ID_025', 'Std_ID_073', 'Std_ID_234', 'Std_ID_027', 'Std_ID_215', 'Std_ID_028', 'Std_ID_208', 'Std_ID_192', 'Std_ID_172', 'Std_ID_015', 'Std_ID_164', 'Std_ID_110', 'Std_ID_010', 'Std_ID_078', 'Std_ID_006', 'Std_ID_204', 'Std_ID_029']
|
['Std_ID_003', 'Std_ID_004', 'Std_ID_007', 'Std_ID_008', 'Std_ID_011', 'Std_ID_012', 'Std_ID_015', 'Std_ID_016', 'Std_ID_019', 'Std_ID_020', 'Std_ID_023', 'Std_ID_024', 'Std_ID_027', 'Std_ID_028', 'Std_ID_031', 'Std_ID_032', 'Std_ID_035', 'Std_ID_036', 'Std_ID_039', 'Std_ID_040', 'Std_ID_043', 'Std_ID_044', 'Std_ID_047', 'Std_ID_048', 'Std_ID_051', 'Std_ID_052', 'Std_ID_055', 'Std_ID_056', 'Std_ID_059', 'Std_ID_060', 'Std_ID_063', 'Std_ID_064', 'Std_ID_067', 'Std_ID_068', 'Std_ID_071', 'Std_ID_072', 'Std_ID_075']
|
||||||
|
|
||||||
CourseCode_07
|
CourseCode_07
|
||||||
['Std_ID_040', 'Std_ID_102', 'Std_ID_186', 'Std_ID_206', 'Std_ID_113', 'Std_ID_135', 'Std_ID_145', 'Std_ID_165', 'Std_ID_028', 'Std_ID_235', 'Std_ID_144', 'Std_ID_085', 'Std_ID_026', 'Std_ID_203', 'Std_ID_231', 'Std_ID_124', 'Std_ID_190', 'Std_ID_089', 'Std_ID_074', 'Std_ID_222', 'Std_ID_179', 'Std_ID_127', 'Std_ID_041', 'Std_ID_133', 'Std_ID_181', 'Std_ID_095', 'Std_ID_034', 'Std_ID_219', 'Std_ID_148', 'Std_ID_037', 'Std_ID_061', 'Std_ID_188', 'Std_ID_171', 'Std_ID_238', 'Std_ID_242', 'Std_ID_029', 'Std_ID_182', 'Std_ID_072', 'Std_ID_161', 'Std_ID_093']
|
['Std_ID_076', 'Std_ID_077', 'Std_ID_078', 'Std_ID_079', 'Std_ID_080', 'Std_ID_081', 'Std_ID_082', 'Std_ID_083', 'Std_ID_084', 'Std_ID_085', 'Std_ID_086', 'Std_ID_087', 'Std_ID_088', 'Std_ID_089', 'Std_ID_090', 'Std_ID_091', 'Std_ID_092', 'Std_ID_093', 'Std_ID_094', 'Std_ID_095', 'Std_ID_096', 'Std_ID_097', 'Std_ID_098', 'Std_ID_099', 'Std_ID_100', 'Std_ID_101', 'Std_ID_102', 'Std_ID_103', 'Std_ID_104', 'Std_ID_105', 'Std_ID_106', 'Std_ID_107', 'Std_ID_108', 'Std_ID_109', 'Std_ID_110', 'Std_ID_111', 'Std_ID_112', 'Std_ID_113', 'Std_ID_114', 'Std_ID_115', 'Std_ID_116', 'Std_ID_117', 'Std_ID_118', 'Std_ID_119', 'Std_ID_120', 'Std_ID_121', 'Std_ID_122', 'Std_ID_123', 'Std_ID_124', 'Std_ID_125', 'Std_ID_126', 'Std_ID_127', 'Std_ID_128']
|
||||||
|
|
||||||
CourseCode_08
|
CourseCode_08
|
||||||
['Std_ID_009', 'Std_ID_108', 'Std_ID_116', 'Std_ID_111', 'Std_ID_058', 'Std_ID_086', 'Std_ID_128', 'Std_ID_106', 'Std_ID_187', 'Std_ID_115', 'Std_ID_101', 'Std_ID_096', 'Std_ID_063', 'Std_ID_192', 'Std_ID_091', 'Std_ID_195', 'Std_ID_236', 'Std_ID_039', 'Std_ID_042', 'Std_ID_052', 'Std_ID_032', 'Std_ID_137', 'Std_ID_181', 'Std_ID_071', 'Std_ID_127', 'Std_ID_130', 'Std_ID_089', 'Std_ID_165', 'Std_ID_175', 'Std_ID_207', 'Std_ID_121', 'Std_ID_233', 'Std_ID_033', 'Std_ID_080', 'Std_ID_240', 'Std_ID_152', 'Std_ID_209', 'Std_ID_050', 'Std_ID_017', 'Std_ID_075']
|
['Std_ID_129', 'Std_ID_133', 'Std_ID_137', 'Std_ID_141', 'Std_ID_145', 'Std_ID_149', 'Std_ID_153', 'Std_ID_157', 'Std_ID_161', 'Std_ID_165', 'Std_ID_169', 'Std_ID_173', 'Std_ID_177', 'Std_ID_181', 'Std_ID_185', 'Std_ID_189', 'Std_ID_193', 'Std_ID_197', 'Std_ID_201', 'Std_ID_205', 'Std_ID_209', 'Std_ID_213', 'Std_ID_217', 'Std_ID_221', 'Std_ID_225', 'Std_ID_229', 'Std_ID_233', 'Std_ID_237', 'Std_ID_241', 'Std_ID_245', 'Std_ID_249', 'Std_ID_253', 'Std_ID_050', 'Std_ID_051', 'Std_ID_052']
|
||||||
|
|
||||||
CourseCode_09
|
CourseCode_09
|
||||||
['Std_ID_043', 'Std_ID_203', 'Std_ID_040', 'Std_ID_163', 'Std_ID_142', 'Std_ID_137', 'Std_ID_220', 'Std_ID_126', 'Std_ID_032', 'Std_ID_157', 'Std_ID_159', 'Std_ID_219', 'Std_ID_175', 'Std_ID_015', 'Std_ID_177', 'Std_ID_217', 'Std_ID_008', 'Std_ID_070', 'Std_ID_048', 'Std_ID_033', 'Std_ID_188', 'Std_ID_078', 'Std_ID_097', 'Std_ID_121', 'Std_ID_183', 'Std_ID_016', 'Std_ID_181', 'Std_ID_080', 'Std_ID_119', 'Std_ID_206', 'Std_ID_093', 'Std_ID_195', 'Std_ID_002', 'Std_ID_098', 'Std_ID_200', 'Std_ID_090', 'Std_ID_167', 'Std_ID_088', 'Std_ID_041', 'Std_ID_164']
|
['Std_ID_130', 'Std_ID_134', 'Std_ID_138', 'Std_ID_142', 'Std_ID_146', 'Std_ID_150', 'Std_ID_154', 'Std_ID_158', 'Std_ID_162', 'Std_ID_166', 'Std_ID_170', 'Std_ID_174', 'Std_ID_178', 'Std_ID_182', 'Std_ID_186', 'Std_ID_190', 'Std_ID_194', 'Std_ID_198', 'Std_ID_202', 'Std_ID_206', 'Std_ID_210', 'Std_ID_214', 'Std_ID_218', 'Std_ID_222', 'Std_ID_226', 'Std_ID_230', 'Std_ID_234', 'Std_ID_238', 'Std_ID_242', 'Std_ID_246', 'Std_ID_250', 'Std_ID_254', 'Std_ID_053', 'Std_ID_054', 'Std_ID_055']
|
||||||
|
|
||||||
CourseCode_10
|
CourseCode_10
|
||||||
['Std_ID_229', 'Std_ID_167', 'Std_ID_228', 'Std_ID_193', 'Std_ID_025', 'Std_ID_205', 'Std_ID_163', 'Std_ID_225', 'Std_ID_194', 'Std_ID_240', 'Std_ID_247', 'Std_ID_233', 'Std_ID_181', 'Std_ID_121', 'Std_ID_152', 'Std_ID_131', 'Std_ID_026', 'Std_ID_217', 'Std_ID_124', 'Std_ID_010', 'Std_ID_054', 'Std_ID_129', 'Std_ID_003', 'Std_ID_211', 'Std_ID_090', 'Std_ID_092', 'Std_ID_024', 'Std_ID_144', 'Std_ID_201', 'Std_ID_049', 'Std_ID_171', 'Std_ID_082', 'Std_ID_136', 'Std_ID_042', 'Std_ID_224', 'Std_ID_027', 'Std_ID_021', 'Std_ID_160', 'Std_ID_235', 'Std_ID_072']
|
['Std_ID_131', 'Std_ID_135', 'Std_ID_139', 'Std_ID_143', 'Std_ID_147', 'Std_ID_151', 'Std_ID_155', 'Std_ID_159', 'Std_ID_163', 'Std_ID_167', 'Std_ID_171', 'Std_ID_175', 'Std_ID_179', 'Std_ID_183', 'Std_ID_187', 'Std_ID_191', 'Std_ID_195', 'Std_ID_199', 'Std_ID_203', 'Std_ID_207', 'Std_ID_211', 'Std_ID_215', 'Std_ID_219', 'Std_ID_223', 'Std_ID_227', 'Std_ID_231', 'Std_ID_235', 'Std_ID_239', 'Std_ID_243', 'Std_ID_247', 'Std_ID_251', 'Std_ID_255', 'Std_ID_056', 'Std_ID_057', 'Std_ID_058']
|
||||||
|
|
||||||
CourseCode_11
|
CourseCode_11
|
||||||
['Std_ID_208', 'Std_ID_237', 'Std_ID_061', 'Std_ID_133', 'Std_ID_119', 'Std_ID_132', 'Std_ID_168', 'Std_ID_238', 'Std_ID_170', 'Std_ID_190', 'Std_ID_066', 'Std_ID_093', 'Std_ID_243', 'Std_ID_148', 'Std_ID_205', 'Std_ID_033', 'Std_ID_078', 'Std_ID_191', 'Std_ID_111', 'Std_ID_090', 'Std_ID_079', 'Std_ID_083', 'Std_ID_086', 'Std_ID_020', 'Std_ID_029', 'Std_ID_022', 'Std_ID_131', 'Std_ID_071', 'Std_ID_055', 'Std_ID_141', 'Std_ID_049', 'Std_ID_115', 'Std_ID_202', 'Std_ID_122', 'Std_ID_075', 'Std_ID_222', 'Std_ID_149', 'Std_ID_021', 'Std_ID_018', 'Std_ID_124']
|
['Std_ID_132', 'Std_ID_136', 'Std_ID_140', 'Std_ID_144', 'Std_ID_148', 'Std_ID_152', 'Std_ID_156', 'Std_ID_160', 'Std_ID_164', 'Std_ID_168', 'Std_ID_172', 'Std_ID_176', 'Std_ID_180', 'Std_ID_184', 'Std_ID_188', 'Std_ID_192', 'Std_ID_196', 'Std_ID_200', 'Std_ID_204', 'Std_ID_208', 'Std_ID_212', 'Std_ID_216', 'Std_ID_220', 'Std_ID_224', 'Std_ID_228', 'Std_ID_232', 'Std_ID_236', 'Std_ID_240', 'Std_ID_244', 'Std_ID_248', 'Std_ID_252', 'Std_ID_256', 'Std_ID_059', 'Std_ID_060', 'Std_ID_061']
|
||||||
|
|
||||||
CourseCode_12
|
CourseCode_12
|
||||||
['Std_ID_066', 'Std_ID_052', 'Std_ID_091', 'Std_ID_008', 'Std_ID_148', 'Std_ID_003', 'Std_ID_040', 'Std_ID_187', 'Std_ID_170', 'Std_ID_147', 'Std_ID_111', 'Std_ID_027', 'Std_ID_142', 'Std_ID_188', 'Std_ID_202', 'Std_ID_176', 'Std_ID_079', 'Std_ID_145', 'Std_ID_058', 'Std_ID_089', 'Std_ID_190', 'Std_ID_044', 'Std_ID_062', 'Std_ID_112', 'Std_ID_099', 'Std_ID_220', 'Std_ID_203', 'Std_ID_222', 'Std_ID_117', 'Std_ID_061', 'Std_ID_118', 'Std_ID_217', 'Std_ID_109', 'Std_ID_223', 'Std_ID_002', 'Std_ID_019', 'Std_ID_121', 'Std_ID_100', 'Std_ID_152', 'Std_ID_213']
|
['Std_ID_129', 'Std_ID_130', 'Std_ID_133', 'Std_ID_134', 'Std_ID_137', 'Std_ID_138', 'Std_ID_141', 'Std_ID_142', 'Std_ID_145', 'Std_ID_146', 'Std_ID_149', 'Std_ID_150', 'Std_ID_153', 'Std_ID_154', 'Std_ID_157', 'Std_ID_158', 'Std_ID_161', 'Std_ID_162', 'Std_ID_165', 'Std_ID_166', 'Std_ID_169', 'Std_ID_170', 'Std_ID_173', 'Std_ID_174', 'Std_ID_177', 'Std_ID_178', 'Std_ID_181', 'Std_ID_182', 'Std_ID_185', 'Std_ID_186', 'Std_ID_189', 'Std_ID_190', 'Std_ID_062', 'Std_ID_063', 'Std_ID_064']
|
||||||
|
|
||||||
CourseCode_13
|
CourseCode_13
|
||||||
['Std_ID_175', 'Std_ID_205', 'Std_ID_019', 'Std_ID_142', 'Std_ID_243', 'Std_ID_246', 'Std_ID_186', 'Std_ID_228', 'Std_ID_137', 'Std_ID_080', 'Std_ID_130', 'Std_ID_105', 'Std_ID_216', 'Std_ID_201', 'Std_ID_135', 'Std_ID_218', 'Std_ID_096', 'Std_ID_109', 'Std_ID_026', 'Std_ID_229', 'Std_ID_207', 'Std_ID_014', 'Std_ID_179', 'Std_ID_192', 'Std_ID_158', 'Std_ID_102', 'Std_ID_011', 'Std_ID_094', 'Std_ID_057', 'Std_ID_010', 'Std_ID_062', 'Std_ID_090', 'Std_ID_125', 'Std_ID_219', 'Std_ID_153', 'Std_ID_122', 'Std_ID_248', 'Std_ID_181', 'Std_ID_058', 'Std_ID_037']
|
['Std_ID_131', 'Std_ID_132', 'Std_ID_135', 'Std_ID_136', 'Std_ID_139', 'Std_ID_140', 'Std_ID_143', 'Std_ID_144', 'Std_ID_147', 'Std_ID_148', 'Std_ID_151', 'Std_ID_152', 'Std_ID_155', 'Std_ID_156', 'Std_ID_159', 'Std_ID_160', 'Std_ID_163', 'Std_ID_164', 'Std_ID_167', 'Std_ID_168', 'Std_ID_171', 'Std_ID_172', 'Std_ID_175', 'Std_ID_176', 'Std_ID_179', 'Std_ID_180', 'Std_ID_183', 'Std_ID_184', 'Std_ID_187', 'Std_ID_188', 'Std_ID_191', 'Std_ID_192', 'Std_ID_065', 'Std_ID_066', 'Std_ID_067']
|
||||||
|
|
||||||
CourseCode_14
|
CourseCode_14
|
||||||
['Std_ID_018', 'Std_ID_052', 'Std_ID_227', 'Std_ID_003', 'Std_ID_208', 'Std_ID_012', 'Std_ID_162', 'Std_ID_042', 'Std_ID_141', 'Std_ID_063', 'Std_ID_019', 'Std_ID_096', 'Std_ID_192', 'Std_ID_124', 'Std_ID_245', 'Std_ID_200', 'Std_ID_219', 'Std_ID_092', 'Std_ID_222', 'Std_ID_020', 'Std_ID_077', 'Std_ID_109', 'Std_ID_174', 'Std_ID_087', 'Std_ID_028', 'Std_ID_083', 'Std_ID_122', 'Std_ID_201', 'Std_ID_117', 'Std_ID_054', 'Std_ID_080', 'Std_ID_010', 'Std_ID_221', 'Std_ID_131', 'Std_ID_024', 'Std_ID_234', 'Std_ID_036', 'Std_ID_177', 'Std_ID_161', 'Std_ID_126']
|
['Std_ID_193', 'Std_ID_194', 'Std_ID_195', 'Std_ID_196', 'Std_ID_197', 'Std_ID_198', 'Std_ID_199', 'Std_ID_200', 'Std_ID_201', 'Std_ID_202', 'Std_ID_203', 'Std_ID_204', 'Std_ID_205', 'Std_ID_206', 'Std_ID_207', 'Std_ID_208', 'Std_ID_209', 'Std_ID_210', 'Std_ID_211', 'Std_ID_212', 'Std_ID_213', 'Std_ID_214', 'Std_ID_215', 'Std_ID_216', 'Std_ID_217', 'Std_ID_218', 'Std_ID_219', 'Std_ID_220', 'Std_ID_221', 'Std_ID_222', 'Std_ID_223', 'Std_ID_224', 'Std_ID_225', 'Std_ID_226', 'Std_ID_227', 'Std_ID_228', 'Std_ID_229', 'Std_ID_230', 'Std_ID_231', 'Std_ID_232', 'Std_ID_233', 'Std_ID_234', 'Std_ID_235', 'Std_ID_236', 'Std_ID_237', 'Std_ID_238', 'Std_ID_239', 'Std_ID_240', 'Std_ID_241', 'Std_ID_242', 'Std_ID_243', 'Std_ID_244', 'Std_ID_245', 'Std_ID_246', 'Std_ID_247', 'Std_ID_248', 'Std_ID_249', 'Std_ID_250', 'Std_ID_251', 'Std_ID_252', 'Std_ID_253', 'Std_ID_254', 'Std_ID_255', 'Std_ID_256']
|
||||||
|
|
||||||
CourseCode_15
|
CourseCode_15
|
||||||
['Std_ID_142', 'Std_ID_050', 'Std_ID_115', 'Std_ID_076', 'Std_ID_011', 'Std_ID_035', 'Std_ID_191', 'Std_ID_059', 'Std_ID_032', 'Std_ID_030', 'Std_ID_012', 'Std_ID_015', 'Std_ID_150', 'Std_ID_121', 'Std_ID_124', 'Std_ID_061', 'Std_ID_075', 'Std_ID_133', 'Std_ID_166', 'Std_ID_069', 'Std_ID_094', 'Std_ID_158', 'Std_ID_144', 'Std_ID_199', 'Std_ID_096', 'Std_ID_177', 'Std_ID_014', 'Std_ID_022', 'Std_ID_004', 'Std_ID_233', 'Std_ID_172', 'Std_ID_180', 'Std_ID_223', 'Std_ID_073', 'Std_ID_018', 'Std_ID_057', 'Std_ID_224', 'Std_ID_099', 'Std_ID_062', 'Std_ID_232']
|
['Std_ID_257', 'Std_ID_261', 'Std_ID_265', 'Std_ID_269', 'Std_ID_273', 'Std_ID_277', 'Std_ID_281', 'Std_ID_285', 'Std_ID_289', 'Std_ID_293', 'Std_ID_297', 'Std_ID_301', 'Std_ID_305', 'Std_ID_309', 'Std_ID_313', 'Std_ID_317', 'Std_ID_321', 'Std_ID_325', 'Std_ID_329', 'Std_ID_333', 'Std_ID_337', 'Std_ID_341', 'Std_ID_345', 'Std_ID_349', 'Std_ID_353', 'Std_ID_357', 'Std_ID_361', 'Std_ID_365', 'Std_ID_369', 'Std_ID_373', 'Std_ID_377', 'Std_ID_381', 'Std_ID_100', 'Std_ID_101', 'Std_ID_102']
|
||||||
|
|
||||||
CourseCode_16
|
CourseCode_16
|
||||||
['Std_ID_020', 'Std_ID_124', 'Std_ID_097', 'Std_ID_092', 'Std_ID_100', 'Std_ID_119', 'Std_ID_177', 'Std_ID_011', 'Std_ID_017', 'Std_ID_114', 'Std_ID_087', 'Std_ID_007', 'Std_ID_132', 'Std_ID_208', 'Std_ID_082', 'Std_ID_002', 'Std_ID_116', 'Std_ID_057', 'Std_ID_210', 'Std_ID_045', 'Std_ID_005', 'Std_ID_139', 'Std_ID_028', 'Std_ID_051', 'Std_ID_144', 'Std_ID_207', 'Std_ID_056', 'Std_ID_042', 'Std_ID_211', 'Std_ID_231', 'Std_ID_203', 'Std_ID_196', 'Std_ID_009', 'Std_ID_106', 'Std_ID_133', 'Std_ID_151', 'Std_ID_058', 'Std_ID_101', 'Std_ID_125', 'Std_ID_232']
|
['Std_ID_258', 'Std_ID_262', 'Std_ID_266', 'Std_ID_270', 'Std_ID_274', 'Std_ID_278', 'Std_ID_282', 'Std_ID_286', 'Std_ID_290', 'Std_ID_294', 'Std_ID_298', 'Std_ID_302', 'Std_ID_306', 'Std_ID_310', 'Std_ID_314', 'Std_ID_318', 'Std_ID_322', 'Std_ID_326', 'Std_ID_330', 'Std_ID_334', 'Std_ID_338', 'Std_ID_342', 'Std_ID_346', 'Std_ID_350', 'Std_ID_354', 'Std_ID_358', 'Std_ID_362', 'Std_ID_366', 'Std_ID_370', 'Std_ID_374', 'Std_ID_378', 'Std_ID_382', 'Std_ID_103', 'Std_ID_104', 'Std_ID_105']
|
||||||
|
|
||||||
CourseCode_17
|
CourseCode_17
|
||||||
['Std_ID_122', 'Std_ID_224', 'Std_ID_056', 'Std_ID_221', 'Std_ID_054', 'Std_ID_237', 'Std_ID_180', 'Std_ID_052', 'Std_ID_020', 'Std_ID_131', 'Std_ID_106', 'Std_ID_231', 'Std_ID_011', 'Std_ID_064', 'Std_ID_069', 'Std_ID_062', 'Std_ID_239', 'Std_ID_019', 'Std_ID_227', 'Std_ID_053', 'Std_ID_119', 'Std_ID_160', 'Std_ID_184', 'Std_ID_240', 'Std_ID_250', 'Std_ID_030', 'Std_ID_177', 'Std_ID_241', 'Std_ID_038', 'Std_ID_129', 'Std_ID_098', 'Std_ID_104', 'Std_ID_158', 'Std_ID_026', 'Std_ID_202', 'Std_ID_015', 'Std_ID_058', 'Std_ID_109', 'Std_ID_152', 'Std_ID_190']
|
['Std_ID_259', 'Std_ID_263', 'Std_ID_267', 'Std_ID_271', 'Std_ID_275', 'Std_ID_279', 'Std_ID_283', 'Std_ID_287', 'Std_ID_291', 'Std_ID_295', 'Std_ID_299', 'Std_ID_303', 'Std_ID_307', 'Std_ID_311', 'Std_ID_315', 'Std_ID_319', 'Std_ID_323', 'Std_ID_327', 'Std_ID_331', 'Std_ID_335', 'Std_ID_339', 'Std_ID_343', 'Std_ID_347', 'Std_ID_351', 'Std_ID_355', 'Std_ID_359', 'Std_ID_363', 'Std_ID_367', 'Std_ID_371', 'Std_ID_375', 'Std_ID_379', 'Std_ID_383', 'Std_ID_106', 'Std_ID_107', 'Std_ID_108']
|
||||||
|
|
||||||
CourseCode_18
|
CourseCode_18
|
||||||
['Std_ID_117', 'Std_ID_136', 'Std_ID_149', 'Std_ID_126', 'Std_ID_006', 'Std_ID_063', 'Std_ID_151', 'Std_ID_060', 'Std_ID_012', 'Std_ID_090', 'Std_ID_154', 'Std_ID_240', 'Std_ID_065', 'Std_ID_162', 'Std_ID_102', 'Std_ID_043', 'Std_ID_144', 'Std_ID_121', 'Std_ID_156', 'Std_ID_066', 'Std_ID_083', 'Std_ID_199', 'Std_ID_143', 'Std_ID_047', 'Std_ID_207', 'Std_ID_189', 'Std_ID_177', 'Std_ID_250', 'Std_ID_210', 'Std_ID_197', 'Std_ID_003', 'Std_ID_246', 'Std_ID_077', 'Std_ID_215', 'Std_ID_086', 'Std_ID_204', 'Std_ID_223', 'Std_ID_067', 'Std_ID_115', 'Std_ID_082']
|
['Std_ID_260', 'Std_ID_264', 'Std_ID_268', 'Std_ID_272', 'Std_ID_276', 'Std_ID_280', 'Std_ID_284', 'Std_ID_288', 'Std_ID_292', 'Std_ID_296', 'Std_ID_300', 'Std_ID_304', 'Std_ID_308', 'Std_ID_312', 'Std_ID_316', 'Std_ID_320', 'Std_ID_324', 'Std_ID_328', 'Std_ID_332', 'Std_ID_336', 'Std_ID_340', 'Std_ID_344', 'Std_ID_348', 'Std_ID_352', 'Std_ID_356', 'Std_ID_360', 'Std_ID_364', 'Std_ID_368', 'Std_ID_372', 'Std_ID_376', 'Std_ID_380', 'Std_ID_384', 'Std_ID_109', 'Std_ID_110', 'Std_ID_111']
|
||||||
|
|
||||||
CourseCode_19
|
CourseCode_19
|
||||||
['Std_ID_250', 'Std_ID_067', 'Std_ID_022', 'Std_ID_114', 'Std_ID_060', 'Std_ID_133', 'Std_ID_236', 'Std_ID_039', 'Std_ID_005', 'Std_ID_032', 'Std_ID_071', 'Std_ID_132', 'Std_ID_087', 'Std_ID_229', 'Std_ID_047', 'Std_ID_029', 'Std_ID_235', 'Std_ID_216', 'Std_ID_199', 'Std_ID_204', 'Std_ID_163', 'Std_ID_168', 'Std_ID_147', 'Std_ID_014', 'Std_ID_187', 'Std_ID_179', 'Std_ID_160', 'Std_ID_035', 'Std_ID_167', 'Std_ID_173', 'Std_ID_248', 'Std_ID_026', 'Std_ID_211', 'Std_ID_003', 'Std_ID_112', 'Std_ID_105', 'Std_ID_191', 'Std_ID_095', 'Std_ID_011', 'Std_ID_092']
|
['Std_ID_257', 'Std_ID_258', 'Std_ID_261', 'Std_ID_262', 'Std_ID_265', 'Std_ID_266', 'Std_ID_269', 'Std_ID_270', 'Std_ID_273', 'Std_ID_274', 'Std_ID_277', 'Std_ID_278', 'Std_ID_281', 'Std_ID_282', 'Std_ID_285', 'Std_ID_286', 'Std_ID_289', 'Std_ID_290', 'Std_ID_293', 'Std_ID_294', 'Std_ID_297', 'Std_ID_298', 'Std_ID_301', 'Std_ID_302', 'Std_ID_305', 'Std_ID_306', 'Std_ID_309', 'Std_ID_310', 'Std_ID_313', 'Std_ID_314', 'Std_ID_317', 'Std_ID_318', 'Std_ID_112', 'Std_ID_113', 'Std_ID_114']
|
||||||
|
|
||||||
CourseCode_20
|
CourseCode_20
|
||||||
['Std_ID_222', 'Std_ID_125', 'Std_ID_188', 'Std_ID_088', 'Std_ID_095', 'Std_ID_046', 'Std_ID_201', 'Std_ID_051', 'Std_ID_104', 'Std_ID_130', 'Std_ID_092', 'Std_ID_057', 'Std_ID_217', 'Std_ID_181', 'Std_ID_227', 'Std_ID_136', 'Std_ID_064', 'Std_ID_133', 'Std_ID_059', 'Std_ID_065', 'Std_ID_169', 'Std_ID_233', 'Std_ID_129', 'Std_ID_123', 'Std_ID_193', 'Std_ID_079', 'Std_ID_172', 'Std_ID_204', 'Std_ID_208', 'Std_ID_246', 'Std_ID_001', 'Std_ID_174', 'Std_ID_007', 'Std_ID_189', 'Std_ID_203', 'Std_ID_205', 'Std_ID_183', 'Std_ID_048', 'Std_ID_121', 'Std_ID_177']
|
['Std_ID_259', 'Std_ID_260', 'Std_ID_263', 'Std_ID_264', 'Std_ID_267', 'Std_ID_268', 'Std_ID_271', 'Std_ID_272', 'Std_ID_275', 'Std_ID_276', 'Std_ID_279', 'Std_ID_280', 'Std_ID_283', 'Std_ID_284', 'Std_ID_287', 'Std_ID_288', 'Std_ID_291', 'Std_ID_292', 'Std_ID_295', 'Std_ID_296', 'Std_ID_299', 'Std_ID_300', 'Std_ID_303', 'Std_ID_304', 'Std_ID_307', 'Std_ID_308', 'Std_ID_311', 'Std_ID_312', 'Std_ID_315', 'Std_ID_316', 'Std_ID_319', 'Std_ID_320', 'Std_ID_115', 'Std_ID_116', 'Std_ID_117']
|
||||||
|
|
||||||
|
CourseCode_21
|
||||||
|
['Std_ID_321', 'Std_ID_322', 'Std_ID_323', 'Std_ID_324', 'Std_ID_325', 'Std_ID_326', 'Std_ID_327', 'Std_ID_328', 'Std_ID_329', 'Std_ID_330', 'Std_ID_331', 'Std_ID_332', 'Std_ID_333', 'Std_ID_334', 'Std_ID_335', 'Std_ID_336', 'Std_ID_337', 'Std_ID_338', 'Std_ID_339', 'Std_ID_340', 'Std_ID_341', 'Std_ID_342', 'Std_ID_343', 'Std_ID_344', 'Std_ID_345', 'Std_ID_346', 'Std_ID_347', 'Std_ID_348', 'Std_ID_349', 'Std_ID_350', 'Std_ID_351', 'Std_ID_352', 'Std_ID_353', 'Std_ID_354', 'Std_ID_355', 'Std_ID_356', 'Std_ID_357', 'Std_ID_358', 'Std_ID_359', 'Std_ID_360', 'Std_ID_361', 'Std_ID_362', 'Std_ID_363', 'Std_ID_364', 'Std_ID_365', 'Std_ID_366', 'Std_ID_367', 'Std_ID_368', 'Std_ID_369', 'Std_ID_370', 'Std_ID_371', 'Std_ID_372', 'Std_ID_373', 'Std_ID_374', 'Std_ID_375', 'Std_ID_376', 'Std_ID_377', 'Std_ID_378', 'Std_ID_379', 'Std_ID_380', 'Std_ID_381', 'Std_ID_382', 'Std_ID_383', 'Std_ID_384']
|
||||||
|
|
||||||
|
CourseCode_22
|
||||||
|
['Std_ID_385', 'Std_ID_389', 'Std_ID_393', 'Std_ID_397', 'Std_ID_401', 'Std_ID_405', 'Std_ID_409', 'Std_ID_413', 'Std_ID_417', 'Std_ID_421', 'Std_ID_425', 'Std_ID_429', 'Std_ID_433', 'Std_ID_437', 'Std_ID_441', 'Std_ID_445', 'Std_ID_449', 'Std_ID_453', 'Std_ID_457', 'Std_ID_461', 'Std_ID_465', 'Std_ID_469', 'Std_ID_473', 'Std_ID_477', 'Std_ID_481', 'Std_ID_485', 'Std_ID_489', 'Std_ID_493', 'Std_ID_497', 'Std_ID_150', 'Std_ID_151', 'Std_ID_152']
|
||||||
|
|
||||||
|
CourseCode_23
|
||||||
|
['Std_ID_386', 'Std_ID_390', 'Std_ID_394', 'Std_ID_398', 'Std_ID_402', 'Std_ID_406', 'Std_ID_410', 'Std_ID_414', 'Std_ID_418', 'Std_ID_422', 'Std_ID_426', 'Std_ID_430', 'Std_ID_434', 'Std_ID_438', 'Std_ID_442', 'Std_ID_446', 'Std_ID_450', 'Std_ID_454', 'Std_ID_458', 'Std_ID_462', 'Std_ID_466', 'Std_ID_470', 'Std_ID_474', 'Std_ID_478', 'Std_ID_482', 'Std_ID_486', 'Std_ID_490', 'Std_ID_494', 'Std_ID_498', 'Std_ID_153', 'Std_ID_154', 'Std_ID_155']
|
||||||
|
|
||||||
|
CourseCode_24
|
||||||
|
['Std_ID_387', 'Std_ID_391', 'Std_ID_395', 'Std_ID_399', 'Std_ID_403', 'Std_ID_407', 'Std_ID_411', 'Std_ID_415', 'Std_ID_419', 'Std_ID_423', 'Std_ID_427', 'Std_ID_431', 'Std_ID_435', 'Std_ID_439', 'Std_ID_443', 'Std_ID_447', 'Std_ID_451', 'Std_ID_455', 'Std_ID_459', 'Std_ID_463', 'Std_ID_467', 'Std_ID_471', 'Std_ID_475', 'Std_ID_479', 'Std_ID_483', 'Std_ID_487', 'Std_ID_491', 'Std_ID_495', 'Std_ID_499', 'Std_ID_156', 'Std_ID_157', 'Std_ID_158']
|
||||||
|
|
||||||
|
CourseCode_25
|
||||||
|
['Std_ID_388', 'Std_ID_392', 'Std_ID_396', 'Std_ID_400', 'Std_ID_404', 'Std_ID_408', 'Std_ID_412', 'Std_ID_416', 'Std_ID_420', 'Std_ID_424', 'Std_ID_428', 'Std_ID_432', 'Std_ID_436', 'Std_ID_440', 'Std_ID_444', 'Std_ID_448', 'Std_ID_452', 'Std_ID_456', 'Std_ID_460', 'Std_ID_464', 'Std_ID_468', 'Std_ID_472', 'Std_ID_476', 'Std_ID_480', 'Std_ID_484', 'Std_ID_488', 'Std_ID_492', 'Std_ID_496', 'Std_ID_500', 'Std_ID_159', 'Std_ID_160', 'Std_ID_161']
|
||||||
|
|
||||||
|
CourseCode_26
|
||||||
|
['Std_ID_385', 'Std_ID_386', 'Std_ID_389', 'Std_ID_390', 'Std_ID_393', 'Std_ID_394', 'Std_ID_397', 'Std_ID_398', 'Std_ID_401', 'Std_ID_402', 'Std_ID_405', 'Std_ID_406', 'Std_ID_409', 'Std_ID_410', 'Std_ID_413', 'Std_ID_414', 'Std_ID_417', 'Std_ID_418', 'Std_ID_421', 'Std_ID_422', 'Std_ID_425', 'Std_ID_426', 'Std_ID_429', 'Std_ID_430', 'Std_ID_433', 'Std_ID_434', 'Std_ID_437', 'Std_ID_438', 'Std_ID_441', 'Std_ID_442', 'Std_ID_445', 'Std_ID_446', 'Std_ID_449', 'Std_ID_450', 'Std_ID_162', 'Std_ID_163', 'Std_ID_164']
|
||||||
|
|
||||||
|
CourseCode_27
|
||||||
|
['Std_ID_387', 'Std_ID_388', 'Std_ID_391', 'Std_ID_392', 'Std_ID_395', 'Std_ID_396', 'Std_ID_399', 'Std_ID_400', 'Std_ID_403', 'Std_ID_404', 'Std_ID_407', 'Std_ID_408', 'Std_ID_411', 'Std_ID_412', 'Std_ID_415', 'Std_ID_416', 'Std_ID_419', 'Std_ID_420', 'Std_ID_423', 'Std_ID_424', 'Std_ID_427', 'Std_ID_428', 'Std_ID_431', 'Std_ID_432', 'Std_ID_435', 'Std_ID_436', 'Std_ID_439', 'Std_ID_440', 'Std_ID_443', 'Std_ID_444', 'Std_ID_447', 'Std_ID_448', 'Std_ID_451', 'Std_ID_452', 'Std_ID_165', 'Std_ID_166', 'Std_ID_167']
|
||||||
|
|
||||||
|
CourseCode_28
|
||||||
|
['Std_ID_453', 'Std_ID_454', 'Std_ID_455', 'Std_ID_456', 'Std_ID_457', 'Std_ID_458', 'Std_ID_459', 'Std_ID_460', 'Std_ID_461', 'Std_ID_462', 'Std_ID_463', 'Std_ID_464', 'Std_ID_465', 'Std_ID_466', 'Std_ID_467', 'Std_ID_468', 'Std_ID_469', 'Std_ID_470', 'Std_ID_471', 'Std_ID_472', 'Std_ID_473', 'Std_ID_474', 'Std_ID_475', 'Std_ID_476', 'Std_ID_477', 'Std_ID_478', 'Std_ID_479', 'Std_ID_480', 'Std_ID_481', 'Std_ID_482', 'Std_ID_483', 'Std_ID_484', 'Std_ID_485', 'Std_ID_486', 'Std_ID_487', 'Std_ID_488', 'Std_ID_489', 'Std_ID_490', 'Std_ID_491', 'Std_ID_492', 'Std_ID_493', 'Std_ID_494', 'Std_ID_495', 'Std_ID_496', 'Std_ID_497', 'Std_ID_498', 'Std_ID_499', 'Std_ID_500']
|
||||||
|
|
||||||
|
CourseCode_29
|
||||||
|
['Std_ID_001', 'Std_ID_025', 'Std_ID_050', 'Std_ID_075', 'Std_ID_100', 'Std_ID_125', 'Std_ID_150', 'Std_ID_175', 'Std_ID_200', 'Std_ID_225', 'Std_ID_250', 'Std_ID_275', 'Std_ID_300', 'Std_ID_325', 'Std_ID_350', 'Std_ID_375', 'Std_ID_400', 'Std_ID_425', 'Std_ID_450', 'Std_ID_475', 'Std_ID_500']
|
||||||
|
|
||||||
|
CourseCode_30
|
||||||
|
['Std_ID_010', 'Std_ID_020', 'Std_ID_030', 'Std_ID_040', 'Std_ID_060', 'Std_ID_070', 'Std_ID_080', 'Std_ID_090', 'Std_ID_110', 'Std_ID_120', 'Std_ID_130', 'Std_ID_140', 'Std_ID_160', 'Std_ID_170', 'Std_ID_180', 'Std_ID_190', 'Std_ID_210', 'Std_ID_220', 'Std_ID_230', 'Std_ID_240', 'Std_ID_260', 'Std_ID_270', 'Std_ID_280', 'Std_ID_290', 'Std_ID_310', 'Std_ID_320', 'Std_ID_330', 'Std_ID_340', 'Std_ID_360', 'Std_ID_370', 'Std_ID_380', 'Std_ID_390', 'Std_ID_410', 'Std_ID_420', 'Std_ID_430', 'Std_ID_440', 'Std_ID_460', 'Std_ID_470', 'Std_ID_480', 'Std_ID_490']
|
||||||
|
|||||||
|
@@ -1,11 +1,16 @@
|
|||||||
ALL OF THE CLASSROOMS; AND THEIR CAPACITIES IN THE SYSTEM
|
ALL OF THE CLASSROOMS; AND THEIR CAPACITIES IN THE SYSTEM
|
||||||
Classroom_01;40
|
Classroom_01;50
|
||||||
Classroom_02;40
|
Classroom_02;50
|
||||||
Classroom_03;40
|
Classroom_03;75
|
||||||
Classroom_04;40
|
Classroom_04;75
|
||||||
Classroom_05;40
|
Classroom_05;100
|
||||||
Classroom_06;40
|
Classroom_06;100
|
||||||
Classroom_07;40
|
Classroom_07;120
|
||||||
Classroom_08;40
|
Classroom_08;120
|
||||||
Classroom_09;40
|
Classroom_09;150
|
||||||
Classroom_10;40
|
Classroom_10;150
|
||||||
|
Classroom_11;200
|
||||||
|
Classroom_12;200
|
||||||
|
Classroom_13;80
|
||||||
|
Classroom_14;80
|
||||||
|
Classroom_15;60
|
||||||
|
|||||||
|
@@ -19,3 +19,13 @@ CourseCode_17
|
|||||||
CourseCode_18
|
CourseCode_18
|
||||||
CourseCode_19
|
CourseCode_19
|
||||||
CourseCode_20
|
CourseCode_20
|
||||||
|
CourseCode_21
|
||||||
|
CourseCode_22
|
||||||
|
CourseCode_23
|
||||||
|
CourseCode_24
|
||||||
|
CourseCode_25
|
||||||
|
CourseCode_26
|
||||||
|
CourseCode_27
|
||||||
|
CourseCode_28
|
||||||
|
CourseCode_29
|
||||||
|
CourseCode_30
|
||||||
|
@@ -249,3 +249,253 @@ Std_ID_247
|
|||||||
Std_ID_248
|
Std_ID_248
|
||||||
Std_ID_249
|
Std_ID_249
|
||||||
Std_ID_250
|
Std_ID_250
|
||||||
|
Std_ID_251
|
||||||
|
Std_ID_252
|
||||||
|
Std_ID_253
|
||||||
|
Std_ID_254
|
||||||
|
Std_ID_255
|
||||||
|
Std_ID_256
|
||||||
|
Std_ID_257
|
||||||
|
Std_ID_258
|
||||||
|
Std_ID_259
|
||||||
|
Std_ID_260
|
||||||
|
Std_ID_261
|
||||||
|
Std_ID_262
|
||||||
|
Std_ID_263
|
||||||
|
Std_ID_264
|
||||||
|
Std_ID_265
|
||||||
|
Std_ID_266
|
||||||
|
Std_ID_267
|
||||||
|
Std_ID_268
|
||||||
|
Std_ID_269
|
||||||
|
Std_ID_270
|
||||||
|
Std_ID_271
|
||||||
|
Std_ID_272
|
||||||
|
Std_ID_273
|
||||||
|
Std_ID_274
|
||||||
|
Std_ID_275
|
||||||
|
Std_ID_276
|
||||||
|
Std_ID_277
|
||||||
|
Std_ID_278
|
||||||
|
Std_ID_279
|
||||||
|
Std_ID_280
|
||||||
|
Std_ID_281
|
||||||
|
Std_ID_282
|
||||||
|
Std_ID_283
|
||||||
|
Std_ID_284
|
||||||
|
Std_ID_285
|
||||||
|
Std_ID_286
|
||||||
|
Std_ID_287
|
||||||
|
Std_ID_288
|
||||||
|
Std_ID_289
|
||||||
|
Std_ID_290
|
||||||
|
Std_ID_291
|
||||||
|
Std_ID_292
|
||||||
|
Std_ID_293
|
||||||
|
Std_ID_294
|
||||||
|
Std_ID_295
|
||||||
|
Std_ID_296
|
||||||
|
Std_ID_297
|
||||||
|
Std_ID_298
|
||||||
|
Std_ID_299
|
||||||
|
Std_ID_300
|
||||||
|
Std_ID_301
|
||||||
|
Std_ID_302
|
||||||
|
Std_ID_303
|
||||||
|
Std_ID_304
|
||||||
|
Std_ID_305
|
||||||
|
Std_ID_306
|
||||||
|
Std_ID_307
|
||||||
|
Std_ID_308
|
||||||
|
Std_ID_309
|
||||||
|
Std_ID_310
|
||||||
|
Std_ID_311
|
||||||
|
Std_ID_312
|
||||||
|
Std_ID_313
|
||||||
|
Std_ID_314
|
||||||
|
Std_ID_315
|
||||||
|
Std_ID_316
|
||||||
|
Std_ID_317
|
||||||
|
Std_ID_318
|
||||||
|
Std_ID_319
|
||||||
|
Std_ID_320
|
||||||
|
Std_ID_321
|
||||||
|
Std_ID_322
|
||||||
|
Std_ID_323
|
||||||
|
Std_ID_324
|
||||||
|
Std_ID_325
|
||||||
|
Std_ID_326
|
||||||
|
Std_ID_327
|
||||||
|
Std_ID_328
|
||||||
|
Std_ID_329
|
||||||
|
Std_ID_330
|
||||||
|
Std_ID_331
|
||||||
|
Std_ID_332
|
||||||
|
Std_ID_333
|
||||||
|
Std_ID_334
|
||||||
|
Std_ID_335
|
||||||
|
Std_ID_336
|
||||||
|
Std_ID_337
|
||||||
|
Std_ID_338
|
||||||
|
Std_ID_339
|
||||||
|
Std_ID_340
|
||||||
|
Std_ID_341
|
||||||
|
Std_ID_342
|
||||||
|
Std_ID_343
|
||||||
|
Std_ID_344
|
||||||
|
Std_ID_345
|
||||||
|
Std_ID_346
|
||||||
|
Std_ID_347
|
||||||
|
Std_ID_348
|
||||||
|
Std_ID_349
|
||||||
|
Std_ID_350
|
||||||
|
Std_ID_351
|
||||||
|
Std_ID_352
|
||||||
|
Std_ID_353
|
||||||
|
Std_ID_354
|
||||||
|
Std_ID_355
|
||||||
|
Std_ID_356
|
||||||
|
Std_ID_357
|
||||||
|
Std_ID_358
|
||||||
|
Std_ID_359
|
||||||
|
Std_ID_360
|
||||||
|
Std_ID_361
|
||||||
|
Std_ID_362
|
||||||
|
Std_ID_363
|
||||||
|
Std_ID_364
|
||||||
|
Std_ID_365
|
||||||
|
Std_ID_366
|
||||||
|
Std_ID_367
|
||||||
|
Std_ID_368
|
||||||
|
Std_ID_369
|
||||||
|
Std_ID_370
|
||||||
|
Std_ID_371
|
||||||
|
Std_ID_372
|
||||||
|
Std_ID_373
|
||||||
|
Std_ID_374
|
||||||
|
Std_ID_375
|
||||||
|
Std_ID_376
|
||||||
|
Std_ID_377
|
||||||
|
Std_ID_378
|
||||||
|
Std_ID_379
|
||||||
|
Std_ID_380
|
||||||
|
Std_ID_381
|
||||||
|
Std_ID_382
|
||||||
|
Std_ID_383
|
||||||
|
Std_ID_384
|
||||||
|
Std_ID_385
|
||||||
|
Std_ID_386
|
||||||
|
Std_ID_387
|
||||||
|
Std_ID_388
|
||||||
|
Std_ID_389
|
||||||
|
Std_ID_390
|
||||||
|
Std_ID_391
|
||||||
|
Std_ID_392
|
||||||
|
Std_ID_393
|
||||||
|
Std_ID_394
|
||||||
|
Std_ID_395
|
||||||
|
Std_ID_396
|
||||||
|
Std_ID_397
|
||||||
|
Std_ID_398
|
||||||
|
Std_ID_399
|
||||||
|
Std_ID_400
|
||||||
|
Std_ID_401
|
||||||
|
Std_ID_402
|
||||||
|
Std_ID_403
|
||||||
|
Std_ID_404
|
||||||
|
Std_ID_405
|
||||||
|
Std_ID_406
|
||||||
|
Std_ID_407
|
||||||
|
Std_ID_408
|
||||||
|
Std_ID_409
|
||||||
|
Std_ID_410
|
||||||
|
Std_ID_411
|
||||||
|
Std_ID_412
|
||||||
|
Std_ID_413
|
||||||
|
Std_ID_414
|
||||||
|
Std_ID_415
|
||||||
|
Std_ID_416
|
||||||
|
Std_ID_417
|
||||||
|
Std_ID_418
|
||||||
|
Std_ID_419
|
||||||
|
Std_ID_420
|
||||||
|
Std_ID_421
|
||||||
|
Std_ID_422
|
||||||
|
Std_ID_423
|
||||||
|
Std_ID_424
|
||||||
|
Std_ID_425
|
||||||
|
Std_ID_426
|
||||||
|
Std_ID_427
|
||||||
|
Std_ID_428
|
||||||
|
Std_ID_429
|
||||||
|
Std_ID_430
|
||||||
|
Std_ID_431
|
||||||
|
Std_ID_432
|
||||||
|
Std_ID_433
|
||||||
|
Std_ID_434
|
||||||
|
Std_ID_435
|
||||||
|
Std_ID_436
|
||||||
|
Std_ID_437
|
||||||
|
Std_ID_438
|
||||||
|
Std_ID_439
|
||||||
|
Std_ID_440
|
||||||
|
Std_ID_441
|
||||||
|
Std_ID_442
|
||||||
|
Std_ID_443
|
||||||
|
Std_ID_444
|
||||||
|
Std_ID_445
|
||||||
|
Std_ID_446
|
||||||
|
Std_ID_447
|
||||||
|
Std_ID_448
|
||||||
|
Std_ID_449
|
||||||
|
Std_ID_450
|
||||||
|
Std_ID_451
|
||||||
|
Std_ID_452
|
||||||
|
Std_ID_453
|
||||||
|
Std_ID_454
|
||||||
|
Std_ID_455
|
||||||
|
Std_ID_456
|
||||||
|
Std_ID_457
|
||||||
|
Std_ID_458
|
||||||
|
Std_ID_459
|
||||||
|
Std_ID_460
|
||||||
|
Std_ID_461
|
||||||
|
Std_ID_462
|
||||||
|
Std_ID_463
|
||||||
|
Std_ID_464
|
||||||
|
Std_ID_465
|
||||||
|
Std_ID_466
|
||||||
|
Std_ID_467
|
||||||
|
Std_ID_468
|
||||||
|
Std_ID_469
|
||||||
|
Std_ID_470
|
||||||
|
Std_ID_471
|
||||||
|
Std_ID_472
|
||||||
|
Std_ID_473
|
||||||
|
Std_ID_474
|
||||||
|
Std_ID_475
|
||||||
|
Std_ID_476
|
||||||
|
Std_ID_477
|
||||||
|
Std_ID_478
|
||||||
|
Std_ID_479
|
||||||
|
Std_ID_480
|
||||||
|
Std_ID_481
|
||||||
|
Std_ID_482
|
||||||
|
Std_ID_483
|
||||||
|
Std_ID_484
|
||||||
|
Std_ID_485
|
||||||
|
Std_ID_486
|
||||||
|
Std_ID_487
|
||||||
|
Std_ID_488
|
||||||
|
Std_ID_489
|
||||||
|
Std_ID_490
|
||||||
|
Std_ID_491
|
||||||
|
Std_ID_492
|
||||||
|
Std_ID_493
|
||||||
|
Std_ID_494
|
||||||
|
Std_ID_495
|
||||||
|
Std_ID_496
|
||||||
|
Std_ID_497
|
||||||
|
Std_ID_498
|
||||||
|
Std_ID_499
|
||||||
|
Std_ID_500
|
||||||
|
@@ -6,106 +6,262 @@ import java.util.*;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for generating exam schedules using Constraint Satisfaction Problem
|
* Service for generating exam schedules using a greedy constraint-based
|
||||||
* (CSP) solving.
|
* algorithm.
|
||||||
* Implements backtracking algorithm with MRV and LCV heuristics.
|
*
|
||||||
* Works with the day/timeSlotIndex based ExamAssignment architecture.
|
* Constraints enforced:
|
||||||
|
* 1. No student can have two exams at the same time
|
||||||
|
* 2. No student can have more than 2 exams per day
|
||||||
|
* 3. Students need at least 1 hour break between consecutive exams
|
||||||
|
* 4. Number of concurrent exams cannot exceed available classrooms
|
||||||
|
*
|
||||||
|
* Features:
|
||||||
|
* - Multiple exams can be scheduled in the same time slot (in different
|
||||||
|
* classrooms)
|
||||||
|
* - Timeout protection (30 seconds max)
|
||||||
|
* - Clear error messages on failure
|
||||||
*/
|
*/
|
||||||
public class ScheduleGeneratorService {
|
public class ScheduleGeneratorService {
|
||||||
private final DataManager dataManager;
|
private final DataManager dataManager;
|
||||||
private final ConstraintValidator validator;
|
|
||||||
private final AtomicBoolean cancelled;
|
private final AtomicBoolean cancelled;
|
||||||
private ProgressListener progressListener;
|
private ProgressListener progressListener;
|
||||||
|
|
||||||
|
// Timeout in milliseconds (30 seconds)
|
||||||
|
private static final long TIMEOUT_MS = 30000;
|
||||||
|
|
||||||
|
// Minimum break between exams in slots (1 hour = 1 slot typically)
|
||||||
|
private static final int MIN_BREAK_SLOTS = 1;
|
||||||
|
|
||||||
|
// Maximum exams per student per day
|
||||||
|
private static final int MAX_EXAMS_PER_DAY = 2;
|
||||||
|
|
||||||
public ScheduleGeneratorService() {
|
public ScheduleGeneratorService() {
|
||||||
this.dataManager = DataManager.getInstance();
|
this.dataManager = DataManager.getInstance();
|
||||||
this.validator = new ConstraintValidator();
|
|
||||||
this.cancelled = new AtomicBoolean(false);
|
this.cancelled = new AtomicBoolean(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an exam schedule based on configuration.
|
* Generate an exam schedule based on configuration.
|
||||||
* Uses multi-restart optimization to find the best schedule among multiple attempts.
|
* Uses greedy algorithm with conflict detection.
|
||||||
*/
|
*/
|
||||||
public ScheduleResult generateSchedule(ScheduleConfiguration config) {
|
public ScheduleResult generateSchedule(ScheduleConfiguration config) {
|
||||||
cancelled.set(false);
|
cancelled.set(false);
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
if (dataManager.getTotalCourses() == 0) {
|
if (dataManager.getTotalCourses() == 0) {
|
||||||
return ScheduleResult.failure("No courses to schedule");
|
return ScheduleResult.failure("No courses to schedule. Please import course data first.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataManager.getTotalClassrooms() == 0) {
|
if (dataManager.getTotalClassrooms() == 0) {
|
||||||
return ScheduleResult.failure("No classrooms available");
|
return ScheduleResult.failure("No classrooms available. Please import classroom data first.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get courses ordered by MRV heuristic
|
List<Course> courses = new ArrayList<>(dataManager.getCourses());
|
||||||
List<Course> coursesToSchedule = getCoursesOrderedByMRV();
|
List<Classroom> classrooms = new ArrayList<>(dataManager.getClassrooms());
|
||||||
|
|
||||||
// Multi-restart optimization: try multiple schedules and pick the best
|
// Build conflict graph: which courses share students
|
||||||
int numRestarts = 5; // Generate 5 different schedules
|
Map<String, Set<String>> conflictGraph = buildConflictGraph(courses);
|
||||||
ScheduleState bestSchedule = null;
|
|
||||||
double bestScore = Double.MAX_VALUE;
|
|
||||||
int successfulAttempts = 0;
|
|
||||||
|
|
||||||
updateProgress(0, numRestarts, "Generating schedules (multi-restart optimization)...");
|
// Sort courses by number of conflicts (most constrained first)
|
||||||
|
courses.sort((c1, c2) -> {
|
||||||
for (int attempt = 0; attempt < numRestarts; attempt++) {
|
int conflicts1 = conflictGraph.getOrDefault(c1.getCourseCode(), Collections.emptySet()).size();
|
||||||
if (cancelled.get()) {
|
int conflicts2 = conflictGraph.getOrDefault(c2.getCourseCode(), Collections.emptySet()).size();
|
||||||
return ScheduleResult.cancelled();
|
if (conflicts1 != conflicts2) {
|
||||||
|
return Integer.compare(conflicts2, conflicts1); // More conflicts first
|
||||||
}
|
}
|
||||||
|
// Tiebreaker: more students first
|
||||||
|
return Integer.compare(c2.getEnrolledStudentsCount(), c1.getEnrolledStudentsCount());
|
||||||
|
});
|
||||||
|
|
||||||
// Create fresh schedule state for this attempt
|
// Initialize schedule state
|
||||||
ScheduleState scheduleState = initializeScheduleState(config);
|
ScheduleState scheduleState = initializeScheduleState(config);
|
||||||
|
|
||||||
updateProgress(attempt, numRestarts,
|
// Track student exam assignments: studentId -> list of (day, slot) pairs
|
||||||
String.format("Attempt %d/%d: Starting backtracking...", attempt + 1, numRestarts));
|
Map<String, List<int[]>> studentExams = new HashMap<>();
|
||||||
|
|
||||||
// Randomize search order slightly for diversity
|
// Track classroom usage: "day-slot" -> set of used classroom IDs
|
||||||
List<Course> shuffledCourses = new ArrayList<>(coursesToSchedule);
|
Map<String, Set<String>> slotClassrooms = new HashMap<>();
|
||||||
if (attempt > 0) {
|
|
||||||
// Keep MRV heuristic but add small random perturbation
|
int totalCourses = courses.size();
|
||||||
shuffledCourses = perturbCourseOrder(shuffledCourses, attempt);
|
int scheduledCount = 0;
|
||||||
}
|
|
||||||
|
updateProgress(0, totalCourses, "Starting schedule generation...");
|
||||||
// Run backtracking
|
|
||||||
boolean success = backtrack(scheduleState, shuffledCourses, 0, config);
|
// Try to schedule each course
|
||||||
|
for (int i = 0; i < courses.size(); i++) {
|
||||||
if (success) {
|
// Check timeout
|
||||||
successfulAttempts++;
|
if (System.currentTimeMillis() - startTime > TIMEOUT_MS) {
|
||||||
|
return ScheduleResult.failure(
|
||||||
// Evaluate this schedule using objective function
|
String.format("Scheduling timed out after 30 seconds. Scheduled %d/%d courses. " +
|
||||||
double score = ScheduleObjective.evaluateSchedule(scheduleState, config, dataManager);
|
"Try increasing the number of days or time slots.", scheduledCount, totalCourses));
|
||||||
|
|
||||||
updateProgress(attempt + 1, numRestarts,
|
|
||||||
String.format("Attempt %d/%d: Found schedule (score: %.1f, best: %.1f)",
|
|
||||||
attempt + 1, numRestarts, score, bestScore));
|
|
||||||
|
|
||||||
if (score < bestScore) {
|
|
||||||
bestScore = score;
|
|
||||||
bestSchedule = scheduleState.copy();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateProgress(attempt + 1, numRestarts,
|
|
||||||
String.format("Attempt %d/%d: No valid schedule", attempt + 1, numRestarts));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check cancellation
|
||||||
if (cancelled.get()) {
|
if (cancelled.get()) {
|
||||||
return ScheduleResult.cancelled();
|
return ScheduleResult.cancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestSchedule != null) {
|
Course course = courses.get(i);
|
||||||
updateProgress(numRestarts, numRestarts,
|
List<String> enrolledStudentsList = course.getEnrolledStudents();
|
||||||
String.format("Complete! Best schedule: score %.1f (%d/%d attempts succeeded)",
|
Set<String> enrolledStudents = new HashSet<>(enrolledStudentsList);
|
||||||
bestScore, successfulAttempts, numRestarts));
|
|
||||||
return ScheduleResult.success(bestSchedule);
|
updateProgress(i, totalCourses, "Scheduling " + course.getCourseCode() + "...");
|
||||||
} else {
|
|
||||||
return ScheduleResult.failure(
|
// Find a valid slot for this course
|
||||||
"No valid schedule found in " + numRestarts + " attempts. " +
|
boolean assigned = false;
|
||||||
"Try increasing days/slots or relaxing constraints.");
|
String failureReason = "";
|
||||||
|
|
||||||
|
// Try each day and slot
|
||||||
|
dayLoop: for (int day = 0; day < config.getNumDays() && !assigned; day++) {
|
||||||
|
for (int slot = 0; slot < config.getSlotsPerDay() && !assigned; slot++) {
|
||||||
|
// Check if this slot is valid for all enrolled students
|
||||||
|
String slotKey = day + "-" + slot;
|
||||||
|
boolean slotValid = true;
|
||||||
|
String reason = "";
|
||||||
|
|
||||||
|
for (String studentId : enrolledStudents) {
|
||||||
|
// Check constraint 1: No concurrent exams
|
||||||
|
List<int[]> studentExamList = studentExams.getOrDefault(studentId, new ArrayList<>());
|
||||||
|
for (int[] exam : studentExamList) {
|
||||||
|
if (exam[0] == day && exam[1] == slot) {
|
||||||
|
slotValid = false;
|
||||||
|
reason = "Student " + studentId + " already has exam at this time";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!slotValid)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Check constraint 2: Max 2 exams per day
|
||||||
|
int examsToday = 0;
|
||||||
|
for (int[] exam : studentExamList) {
|
||||||
|
if (exam[0] == day)
|
||||||
|
examsToday++;
|
||||||
|
}
|
||||||
|
if (examsToday >= MAX_EXAMS_PER_DAY) {
|
||||||
|
slotValid = false;
|
||||||
|
reason = "Student " + studentId + " already has " + MAX_EXAMS_PER_DAY + " exams on day "
|
||||||
|
+ (day + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check constraint 3: At least 1 hour break between exams
|
||||||
|
for (int[] exam : studentExamList) {
|
||||||
|
if (exam[0] == day) {
|
||||||
|
int slotDiff = Math.abs(exam[1] - slot);
|
||||||
|
if (slotDiff > 0 && slotDiff <= MIN_BREAK_SLOTS) {
|
||||||
|
slotValid = false;
|
||||||
|
reason = "Student " + studentId + " needs at least 1 hour break between exams";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!slotValid)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!slotValid) {
|
||||||
|
failureReason = reason;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check constraint 4: Find available classroom
|
||||||
|
Set<String> usedClassrooms = slotClassrooms.getOrDefault(slotKey, new HashSet<>());
|
||||||
|
Classroom selectedClassroom = null;
|
||||||
|
|
||||||
|
// Sort classrooms by capacity (prefer smallest that fits)
|
||||||
|
List<Classroom> sortedClassrooms = new ArrayList<>(classrooms);
|
||||||
|
sortedClassrooms.sort(Comparator.comparingInt(Classroom::getCapacity));
|
||||||
|
|
||||||
|
for (Classroom classroom : sortedClassrooms) {
|
||||||
|
if (!usedClassrooms.contains(classroom.getClassroomId()) &&
|
||||||
|
classroom.getCapacity() >= course.getEnrolledStudentsCount()) {
|
||||||
|
selectedClassroom = classroom;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedClassroom == null) {
|
||||||
|
failureReason = "No available classroom with sufficient capacity at day " + (day + 1) + " slot "
|
||||||
|
+ (slot + 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All constraints satisfied - assign the exam
|
||||||
|
ExamAssignment assignment = scheduleState.getAssignment(course.getCourseCode());
|
||||||
|
scheduleState.updateAssignment(
|
||||||
|
assignment.getCourseCode(),
|
||||||
|
day,
|
||||||
|
slot,
|
||||||
|
selectedClassroom.getClassroomId());
|
||||||
|
|
||||||
|
// Update tracking structures
|
||||||
|
for (String studentId : enrolledStudents) {
|
||||||
|
studentExams.computeIfAbsent(studentId, k -> new ArrayList<>())
|
||||||
|
.add(new int[] { day, slot });
|
||||||
|
}
|
||||||
|
|
||||||
|
usedClassrooms.add(selectedClassroom.getClassroomId());
|
||||||
|
slotClassrooms.put(slotKey, usedClassrooms);
|
||||||
|
|
||||||
|
assigned = true;
|
||||||
|
scheduledCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!assigned) {
|
||||||
|
return ScheduleResult.failure(
|
||||||
|
String.format("Could not schedule course %s. %s. " +
|
||||||
|
"Scheduled %d/%d courses before failure. " +
|
||||||
|
"Try increasing days/slots or reducing course conflicts.",
|
||||||
|
course.getCourseCode(), failureReason, scheduledCount, totalCourses));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate final schedule
|
||||||
|
int violations = validateSchedule(scheduleState, studentExams);
|
||||||
|
scheduleState.setConstraintViolations(violations);
|
||||||
|
|
||||||
|
updateProgress(totalCourses, totalCourses,
|
||||||
|
String.format("Complete! Scheduled all %d courses.", totalCourses));
|
||||||
|
|
||||||
|
return ScheduleResult.success(scheduleState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build conflict graph - courses that share students cannot be scheduled at the
|
||||||
|
* same time.
|
||||||
|
*/
|
||||||
|
private Map<String, Set<String>> buildConflictGraph(List<Course> courses) {
|
||||||
|
Map<String, Set<String>> conflictGraph = new HashMap<>();
|
||||||
|
|
||||||
|
// Map student to their courses
|
||||||
|
Map<String, Set<String>> studentCourses = new HashMap<>();
|
||||||
|
for (Course course : courses) {
|
||||||
|
for (String studentId : course.getEnrolledStudents()) {
|
||||||
|
studentCourses.computeIfAbsent(studentId, k -> new HashSet<>())
|
||||||
|
.add(course.getCourseCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build conflict edges
|
||||||
|
for (Set<String> coursesOfStudent : studentCourses.values()) {
|
||||||
|
if (coursesOfStudent.size() > 1) {
|
||||||
|
List<String> courseList = new ArrayList<>(coursesOfStudent);
|
||||||
|
for (int i = 0; i < courseList.size(); i++) {
|
||||||
|
for (int j = i + 1; j < courseList.size(); j++) {
|
||||||
|
String c1 = courseList.get(i);
|
||||||
|
String c2 = courseList.get(j);
|
||||||
|
conflictGraph.computeIfAbsent(c1, k -> new HashSet<>()).add(c2);
|
||||||
|
conflictGraph.computeIfAbsent(c2, k -> new HashSet<>()).add(c1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return conflictGraph;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize ScheduleState with configuration.
|
* Initialize ScheduleState with configuration.
|
||||||
@@ -113,7 +269,7 @@ public class ScheduleGeneratorService {
|
|||||||
private ScheduleState initializeScheduleState(ScheduleConfiguration config) {
|
private ScheduleState initializeScheduleState(ScheduleConfiguration config) {
|
||||||
ScheduleState state = new ScheduleState();
|
ScheduleState state = new ScheduleState();
|
||||||
|
|
||||||
// CRITICAL: Set configuration so ScheduleState knows about days/slots
|
// Set configuration so ScheduleState knows about days/slots
|
||||||
state.setConfiguration(config);
|
state.setConfiguration(config);
|
||||||
|
|
||||||
// Set available classrooms
|
// Set available classrooms
|
||||||
@@ -133,257 +289,45 @@ public class ScheduleGeneratorService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backtracking algorithm core.
|
* Validate the final schedule and count any violations.
|
||||||
*/
|
*/
|
||||||
private boolean backtrack(ScheduleState scheduleState, List<Course> courses, int courseIndex,
|
private int validateSchedule(ScheduleState scheduleState, Map<String, List<int[]>> studentExams) {
|
||||||
ScheduleConfiguration config) {
|
int violations = 0;
|
||||||
// Check cancellation
|
|
||||||
if (cancelled.get()) {
|
for (Map.Entry<String, List<int[]>> entry : studentExams.entrySet()) {
|
||||||
return false;
|
List<int[]> exams = entry.getValue();
|
||||||
|
|
||||||
|
// Group exams by day
|
||||||
|
Map<Integer, List<Integer>> examsByDay = new HashMap<>();
|
||||||
|
for (int[] exam : exams) {
|
||||||
|
examsByDay.computeIfAbsent(exam[0], k -> new ArrayList<>()).add(exam[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base case: all courses assigned
|
for (Map.Entry<Integer, List<Integer>> dayEntry : examsByDay.entrySet()) {
|
||||||
if (courseIndex >= courses.size()) {
|
List<Integer> slots = dayEntry.getValue();
|
||||||
return true;
|
|
||||||
|
// Check max 2 exams per day
|
||||||
|
if (slots.size() > MAX_EXAMS_PER_DAY) {
|
||||||
|
violations++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Course currentCourse = courses.get(courseIndex);
|
// Check for concurrent exams (should not happen, but validate)
|
||||||
|
Set<Integer> uniqueSlots = new HashSet<>(slots);
|
||||||
// Update progress
|
if (uniqueSlots.size() != slots.size()) {
|
||||||
updateProgress(courseIndex, courses.size(),
|
violations++;
|
||||||
"Scheduling " + currentCourse.getCourseCode() + "...");
|
|
||||||
|
|
||||||
ExamAssignment assignment = scheduleState.getAssignment(currentCourse.getCourseCode());
|
|
||||||
|
|
||||||
// Get time slots ordered by strategy
|
|
||||||
List<DaySlotPair> orderedTimeSlots = getTimeSlotsOrderedByStrategy(config, scheduleState);
|
|
||||||
|
|
||||||
// Try each time slot
|
|
||||||
for (DaySlotPair timeSlot : orderedTimeSlots) {
|
|
||||||
if (cancelled.get()) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get suitable classrooms for this day/slot (ordered by strategy)
|
// Check break time
|
||||||
List<Classroom> suitableClassrooms = getSuitableClassroomsOrdered(
|
Collections.sort(slots);
|
||||||
currentCourse, timeSlot.day, timeSlot.slot, scheduleState, config);
|
for (int i = 1; i < slots.size(); i++) {
|
||||||
|
if (slots.get(i) - slots.get(i - 1) <= MIN_BREAK_SLOTS) {
|
||||||
// Try each classroom
|
violations++;
|
||||||
for (Classroom classroom : suitableClassrooms) {
|
}
|
||||||
// Temporarily assign (using updateAssignment to maintain assignedCourses counter)
|
}
|
||||||
scheduleState.updateAssignment(
|
|
||||||
assignment.getCourseCode(),
|
|
||||||
timeSlot.day,
|
|
||||||
timeSlot.slot,
|
|
||||||
classroom.getClassroomId()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Validate assignment - pass allowBackToBack from config
|
|
||||||
ConstraintValidator.ValidationResult validationResult = validator.validateAssignment(assignment,
|
|
||||||
scheduleState, config.isAllowBackToBackExams());
|
|
||||||
|
|
||||||
if (validationResult.isValid()) {
|
|
||||||
// Assignment is valid, try to assign remaining courses
|
|
||||||
if (backtrack(scheduleState, courses, courseIndex + 1, config)) {
|
|
||||||
return true; // Success!
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backtrack: reset assignment (using updateAssignment to maintain assignedCourses counter)
|
return violations;
|
||||||
scheduleState.updateAssignment(
|
|
||||||
assignment.getCourseCode(),
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No valid assignment found
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MRV Heuristic: Order courses by "most constrained first".
|
|
||||||
*/
|
|
||||||
private List<Course> getCoursesOrderedByMRV() {
|
|
||||||
List<Course> courses = new ArrayList<>(dataManager.getCourses());
|
|
||||||
|
|
||||||
// Sort by number of enrolled students (descending)
|
|
||||||
// More students = more constrained
|
|
||||||
courses.sort((c1, c2) -> Integer.compare(
|
|
||||||
c2.getEnrolledStudentsCount(),
|
|
||||||
c1.getEnrolledStudentsCount()));
|
|
||||||
|
|
||||||
return courses;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add small random perturbation to course order while preserving MRV bias.
|
|
||||||
* This creates diverse schedules for multi-restart optimization.
|
|
||||||
*
|
|
||||||
* @param courses Original course list
|
|
||||||
* @param seed Seed for deterministic randomization
|
|
||||||
* @return Perturbed course list
|
|
||||||
*/
|
|
||||||
private List<Course> perturbCourseOrder(List<Course> courses, int seed) {
|
|
||||||
Random random = new Random(seed * 1000L); // Deterministic seed for reproducibility
|
|
||||||
List<Course> perturbed = new ArrayList<>(courses);
|
|
||||||
|
|
||||||
// Swap 2-3 random pairs (limited perturbation maintains MRV benefits)
|
|
||||||
int swaps = 2 + random.nextInt(2);
|
|
||||||
for (int i = 0; i < swaps && perturbed.size() > 1; i++) {
|
|
||||||
int idx1 = random.nextInt(perturbed.size());
|
|
||||||
int idx2 = random.nextInt(perturbed.size());
|
|
||||||
Collections.swap(perturbed, idx1, idx2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return perturbed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get time slots ordered by optimization strategy.
|
|
||||||
*/
|
|
||||||
private List<DaySlotPair> getTimeSlotsOrderedByStrategy(ScheduleConfiguration config, ScheduleState scheduleState) {
|
|
||||||
List<DaySlotPair> timeSlots = new ArrayList<>();
|
|
||||||
|
|
||||||
// Generate all day/slot combinations
|
|
||||||
for (int day = 0; day < config.getNumDays(); day++) {
|
|
||||||
for (int slot = 0; slot < config.getSlotsPerDay(); slot++) {
|
|
||||||
timeSlots.add(new DaySlotPair(day, slot));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Order based on strategy (deprecated strategies handled in ScheduleObjective)
|
|
||||||
switch (config.getOptimizationStrategy()) {
|
|
||||||
case MINIMIZE_DAYS:
|
|
||||||
// Already in order (day 0 slot 0, day 0 slot 1, ... day 1 slot 0, ...)
|
|
||||||
// This fills earlier days first
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STUDENT_FRIENDLY:
|
|
||||||
// Fill each day completely before moving to next day
|
|
||||||
// Within each day, prefer middle slots (avoid early morning)
|
|
||||||
// Priority: slots 1 and 2 (middle of day) over slots 0 (early) and 3 (late)
|
|
||||||
timeSlots.sort((p1, p2) -> {
|
|
||||||
// Primary: sort by day (fill Day 0 first, then Day 1, etc.)
|
|
||||||
int dayCompare = Integer.compare(p1.day, p2.day);
|
|
||||||
if (dayCompare != 0)
|
|
||||||
return dayCompare;
|
|
||||||
|
|
||||||
// Secondary: within same day, prefer middle slots
|
|
||||||
// Slot priority order: 1 (best), 2 (good), 0 (early morning), 3 (late afternoon)
|
|
||||||
int[] slotPriority = { 2, 0, 1, 3 }; // Maps slot index to priority (lower is better)
|
|
||||||
int priority1 = p1.slot < slotPriority.length ? slotPriority[p1.slot] : p1.slot;
|
|
||||||
int priority2 = p2.slot < slotPriority.length ? slotPriority[p2.slot] : p2.slot;
|
|
||||||
return Integer.compare(priority1, priority2);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// DEFAULT or others: chronological order
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return timeSlots;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get classrooms suitable for a course at a specific day and time slot,
|
|
||||||
* ordered according to optimization strategy.
|
|
||||||
*/
|
|
||||||
private List<Classroom> getSuitableClassroomsOrdered(Course course,
|
|
||||||
int day,
|
|
||||||
int timeSlotIndex,
|
|
||||||
ScheduleState scheduleState,
|
|
||||||
ScheduleConfiguration config) {
|
|
||||||
List<Classroom> suitable = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Classroom classroom : scheduleState.getAvailableClassrooms()) {
|
|
||||||
// Check capacity
|
|
||||||
if (classroom.getCapacity() < course.getEnrolledStudentsCount()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if classroom is available at this time
|
|
||||||
boolean isAvailable = true;
|
|
||||||
for (ExamAssignment assignment : scheduleState.getAssignments().values()) {
|
|
||||||
if (assignment.isAssigned() &&
|
|
||||||
assignment.getClassroomId().equals(classroom.getClassroomId()) &&
|
|
||||||
assignment.getDay() == day &&
|
|
||||||
assignment.getTimeSlotIndex() == timeSlotIndex) {
|
|
||||||
isAvailable = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isAvailable) {
|
|
||||||
suitable.add(classroom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Order based on strategy (deprecated strategies handled in ScheduleObjective)
|
|
||||||
switch (config.getOptimizationStrategy()) {
|
|
||||||
case MINIMIZE_CLASSROOMS:
|
|
||||||
// Prefer classrooms that are already in use (reuse same classrooms)
|
|
||||||
suitable.sort((c1, c2) -> {
|
|
||||||
int usage1 = getClassroomUsageCount(c1.getClassroomId(), scheduleState);
|
|
||||||
int usage2 = getClassroomUsageCount(c2.getClassroomId(), scheduleState);
|
|
||||||
// Sort descending (most used first)
|
|
||||||
return Integer.compare(usage2, usage1);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// DEFAULT: Use round-robin to force distribution across classrooms
|
|
||||||
// Always prefer least-used classrooms to ensure multiple classrooms get used
|
|
||||||
suitable.sort((c1, c2) -> {
|
|
||||||
int usage1 = getClassroomUsageCount(c1.getClassroomId(), scheduleState);
|
|
||||||
int usage2 = getClassroomUsageCount(c2.getClassroomId(), scheduleState);
|
|
||||||
|
|
||||||
// Primary: prefer least-used classrooms
|
|
||||||
int usageCompare = Integer.compare(usage1, usage2);
|
|
||||||
if (usageCompare != 0)
|
|
||||||
return usageCompare;
|
|
||||||
|
|
||||||
// Tiebreaker: prefer smaller capacity (efficient space usage)
|
|
||||||
int capacityCompare = Integer.compare(c1.getCapacity(), c2.getCapacity());
|
|
||||||
if (capacityCompare != 0)
|
|
||||||
return capacityCompare;
|
|
||||||
|
|
||||||
// Final tiebreaker: classroom ID (deterministic)
|
|
||||||
return c1.getClassroomId().compareTo(c2.getClassroomId());
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return suitable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Count how many times a classroom has been used in the current schedule.
|
|
||||||
*/
|
|
||||||
private int getClassroomUsageCount(String classroomId, ScheduleState scheduleState) {
|
|
||||||
int count = 0;
|
|
||||||
for (ExamAssignment assignment : scheduleState.getAssignments().values()) {
|
|
||||||
if (assignment.isAssigned() && assignment.getClassroomId().equals(classroomId)) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class to represent a day/slot pair.
|
|
||||||
*/
|
|
||||||
private static class DaySlotPair {
|
|
||||||
final int day;
|
|
||||||
final int slot;
|
|
||||||
|
|
||||||
DaySlotPair(int day, int slot) {
|
|
||||||
this.day = day;
|
|
||||||
this.slot = slot;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user