/// <summary> /// 根据班级ID获取课程 /// </summary> /// <param name="cl"></param> /// <param name="classID">班级ID</param> /// <returns></returns> public static List <Models.Mixed.UICourse> GetCoursesByClassID(this CLCase cl, string classID) { List <Models.Mixed.UICourse> courses = new List <Models.Mixed.UICourse>(); var classHours = (from ch in cl.ClassHours where ch.ClassID.Equals(classID) select ch); var groups = classHours?.GroupBy(g => g.CourseID); if (groups != null) { foreach (var g in groups) { var course = cl.Courses.FirstOrDefault(ch => ch.ID.Equals(g.Key)); if (course != null) { Models.Mixed.UICourse ui = new Models.Mixed.UICourse() { ID = course.ID, Name = course.Name }; courses.Add(ui); } } } return(courses); }
/// <summary> /// 根据课程选择教师 /// </summary> /// <param name="cp"></param> /// <param name="courseID">科目ID</param> /// <returns>教师</returns> public static List <UITeacher> GetTeachers(this CLCase cp, string courseID) { List <UITeacher> teachers = new List <UITeacher>(); var classhours = (from c in cp.ClassHours from tid in c.TeacherIDs from t in cp.Teachers where tid.Equals(t.ID) select new { c.CourseID, t }); var results = classhours.Where(c => c.CourseID.Equals(courseID)); if (results != null) { var groups = results.GroupBy(r => r.t); foreach (var g in groups) { UITeacher uiTeacher = new UITeacher() { ID = g.Key.ID, Name = g.Key.Name }; teachers.Add(uiTeacher); } } return(teachers); }
/// <summary> /// 根据教师ID获取班级 /// </summary> /// <param name="cl"></param> /// <param name="teacherID">教师ID</param> /// <returns></returns> public static List <Models.Mixed.UIClass> GetClassesByTeacherID(this CLCase cl, string teacherID) { List <Models.Mixed.UIClass> classes = new List <Models.Mixed.UIClass>(); var classHours = (from ch in cl.ClassHours where ch.TeacherIDs.Contains(teacherID) select ch); var groups = classHours?.GroupBy(g => g.ClassID); if (groups != null) { foreach (var g in groups) { var classModel = cl.Classes.FirstOrDefault(ch => ch.ID.Equals(g.Key)); if (classModel != null) { Models.Mixed.UIClass ui = new Models.Mixed.UIClass() { ID = classModel.ID, Name = classModel.Name, }; classes.Add(ui); } } } return(classes); }
/// <summary> /// 获取班级,根据课程ID /// </summary> /// <param name="cl"></param> /// <param name="courseID"></param> /// <returns></returns> public static List <Models.Mixed.UIClass> GetClasses(this CLCase cl, string courseID) { List <Models.Mixed.UIClass> classes = new List <Models.Mixed.UIClass>(); var filter = cl.Classes.Where(c => c.CourseID.Equals(courseID)); if (filter != null) { foreach (var f in filter) { var model = new Models.Mixed.UIClass() { ID = f.ID, CourseID = f.CourseID, Capacity = f.Capacity, LevelID = f.LevelID, StudentIDs = f.StudentIDs, TeacherIDs = f.TeacherIDs, }; var course = cl.Courses.FirstOrDefault(c => c.ID.Equals(f.CourseID)); if (course != null) { var level = course.Levels.FirstOrDefault(l => l.ID.Equals(model.LevelID)); model.Name = f.Name; model.Level = level?.Name; model.Course = course.Name; } classes.Add(model); } } return(classes); }
public static Models.Mixed.UIClass GetClassByID(this CLCase cl, string classID) { var f = cl.Classes.FirstOrDefault(c => c.ID == classID); if (f != null) { var model = new Models.Mixed.UIClass() { ID = f.ID, CourseID = f.CourseID, Capacity = f.Capacity, LevelID = f.LevelID, StudentIDs = f.StudentIDs, TeacherIDs = f.TeacherIDs, }; var course = cl.Courses.FirstOrDefault(c => c.ID.Equals(f.CourseID)); if (course != null) { var level = course.Levels.FirstOrDefault(l => l.ID.Equals(model.LevelID)); model.Name = f.Name; model.Level = level?.Name; model.Course = course.Name; } return(model); } else { return(null); } }
/// <summary> /// Remove Students who's selection in RemovedCombination /// </summary> /// <param name="cLCase"></param> /// <param name="RemovedCombination"></param> /// <returns></returns> public static CLCase GetCaseByRemovedCombination(CLCase cLCase, List <SelectionCombinationModel> RemovedCombination) { List <string> selectionRoads = GetStringFormatBySelectionCombination(RemovedCombination); List <string> studentsToRemoved = new List <string>(); cLCase.Students.ForEach(x => { string preselectionRoad = GetStringFormatByStudentPreselection(x.Preselections); if (selectionRoads.Contains(preselectionRoad)) { studentsToRemoved.Add(x.ID); } }); studentsToRemoved.ForEach(x => { var studentToRemove = cLCase.Students.SingleOrDefault(s => s.ID == x); if (studentToRemove != null) { cLCase.Students.Remove(studentToRemove); } }); return(cLCase); }
public void AddMixedCase(string localID, CLCase model) { if (CLCases.ContainsKey(localID)) { CLCases[localID] = model; } else { CLCases.Add(localID, model); } }
/// <summary> /// 对模型中的学生进行抽样 /// </summary> /// <param name="cLCase"></param> /// <param name="extractionRatio"></param> /// <returns></returns> public static CLCase GetCaseByExtractionRatio(CLCase cLCase, int extractionRatio) { List <string> leftStudentId = new List <string>(); List <string> allStudentId = new List <string>(); List <string> removedStudentId = new List <string>(); List <StudentRoad> studentsRoad = new List <StudentRoad>(); cLCase.Students.ForEach(x => { string preselectionRoad = GetStringFormatByStudentPreselection(x.Preselections); studentsRoad.Add(new StudentRoad { StudentId = x.ID, SelectionRoad = preselectionRoad }); }); List <string> allRoads = studentsRoad.GroupBy(x => x.SelectionRoad)?.Select(x => x.Key)?.ToList() ?? new List <string>(); //每种选择都按照相同的百分比取学生 allRoads.ForEach(x => { int roadStudents = studentsRoad.Where(s => s.SelectionRoad == x)?.Count() ?? 0; int takeStudentNumber = (int)Math.Ceiling((roadStudents * extractionRatio) / 100.0); leftStudentId.AddRange(studentsRoad.Where(sr => sr.SelectionRoad == x).Take(takeStudentNumber).Select(sr => sr.StudentId).ToList()); }); leftStudentId = leftStudentId.Distinct().ToList(); allStudentId = studentsRoad.Select(x => x.StudentId).Distinct().ToList(); removedStudentId = allStudentId.Except(leftStudentId).ToList(); //删除保留之外的学生 removedStudentId.ForEach(x => { var studentToRemove = cLCase.Students.SingleOrDefault(s => s.ID == x); if (studentToRemove != null) { cLCase.Students.Remove(studentToRemove); } }); //更新班额 cLCase.Courses.ForEach(co => { co.Levels.ForEach(le => { int leftStudents = cLCase.Students.Where(s => s.Preselections.Exists(p => p.CourseID == co.ID && p.LevelID == le.ID)).Count(); int classNumber = cLCase.Classes.Where(c => c.CourseID == co.ID && c.LevelID == le.ID).Count(); int avgCapacity = classNumber > 0 ? (int)Math.Ceiling(leftStudents / (decimal)classNumber) : 0; cLCase.Classes.Where(c => c.CourseID == co.ID && c.LevelID == le.ID)?.ToList()?.ForEach(c => { c.Capacity = avgCapacity; }); }); }); return(cLCase); }
public void Serialize(CLCase cl, string localID) { var caseModel = CommonDataManager.GetLocalCase(localID); if (caseModel.Pattern == Models.Enums.PatternTypeEnum.None) { cl.Serialize(localID); } else { cl.SerializePatternCase(localID); } }
public CLCase GetCLCase(string localID) { if (CLCases.ContainsKey(localID)) { return(CLCases[localID]); } else { CLCase newCase = new CLCase(); CLCases.Add(localID, newCase); return(newCase); } }
/// <summary> /// 对模型中的课时进行压缩 /// </summary> /// <param name="cLCase"></param> /// <param name="CompressionRatio"></param> /// <returns></returns> public static CLCase GetCaseClassHourUpdateByTimeCompressionRatio(CLCase cLCase, int CompressionRatio) { #region 更新层上的课时及班级中的课时 cLCase.Courses.ForEach(x => { x.Levels.ForEach(le => { int quotient = le.Lessons / CompressionRatio; int remainder = le.Lessons % CompressionRatio; le.Lessons = quotient + remainder; cLCase.Classes.Where(c => c.CourseID == x.ID && c.LevelID == le.ID).ToList().ForEach(cl => { /* add tags and inactive all useless classhour */ int iIndex = 0; cLCase.ClassHours?.Where(c => c.CourseID == x.ID && c.LevelID == le.ID && c.ClassID == cl.ID)?.ToList()?.ForEach(c => { if (c.TagIDs == null) { c.TagIDs = new List <string>() { }; } switch (iIndex) { case int n when(n < quotient): c.TagIDs.Add(SystemTag.XYTagN.ToString()); break; case int n when(n >= quotient && n < quotient + remainder): c.TagIDs.Add(SystemTag.XYTag1.ToString()); break; case int n when(n >= quotient + remainder): break; default: break; } iIndex++; }); }); }); }); #endregion //重新删除所有无效课时 cLCase.ClassHours.RemoveAll(x => x.TagIDs == null || x.TagIDs.Count == 0); return(cLCase); }
/// <summary> /// 获取课时 /// </summary> /// <param name="cl"></param> /// <param name="ids"></param> /// <returns></returns> public static List <UIClassHour> GetClassHours(this CLCase cl, int[] ids) { List <UIClassHour> results = new List <UIClassHour>(); if (cl == null || ids == null) { return(results); } var teachers = cl.Teachers; var classes = cl.Classes; var courses = cl.Courses; var classHours = (from i in ids from ch in cl.ClassHours where i == ch.ID select ch); foreach (var ch in classHours) { UIClassHour uiClassHour = new UIClassHour(); uiClassHour.ClassID = ch.ClassID; uiClassHour.CourseID = ch.CourseID; uiClassHour.ID = ch.ID; uiClassHour.LevelID = ch.LevelID; uiClassHour.Tags = ch.TagIDs; if (ch.TeacherIDs == null) { uiClassHour.Teachers = new List <TeacherModel>(); } else { uiClassHour.Teachers = (from id in ch.TeacherIDs from t in teachers where t.ID == id select t)?.ToList(); } uiClassHour.Class = classes.FirstOrDefault(c => c.ID.Equals(ch.ClassID))?.Name; var course = courses.FirstOrDefault(c => c.ID.Equals(ch.CourseID)); if (course != null) { var defaultLevel = course.Levels.FirstOrDefault(l => l.ID.Equals(ch.LevelID)); uiClassHour.Course = course.Name; uiClassHour.Level = defaultLevel?.Name; } results.Add(uiClassHour); } return(results); }
public static string GetCLClassCourseInfo(CLCase cLCase, string classID) { string classCourseInfo = string.Empty; if (cLCase != null && !string.IsNullOrEmpty(classID)) { var classObj = cLCase.Classes?.FirstOrDefault(cl => cl.ID == classID); string className = classObj?.Name ?? string.Empty; string courseName = cLCase.Courses?.FirstOrDefault(co => co.ID == classObj.CourseID)?.Name ?? string.Empty; string levelName = cLCase.Courses?.FirstOrDefault(co => co.ID == classObj.CourseID)?.Levels?.FirstOrDefault(le => le.ID == classObj.LevelID)?.Name ?? string.Empty; classCourseInfo = $"{courseName}{levelName}{className}"; } return(classCourseInfo); }
public int GetCompressionRatio(CLCase cLCase) { int compressionRatio = 2; List <int> lessons = cLCase?.Courses?.SelectMany(c => c.Levels)?.Select(le => le.Lessons)?.ToList() ?? new List <int>(); if (lessons.Max() == lessons.Min()) { compressionRatio = lessons.Min(); } else if (lessons.Max() > 1) { compressionRatio = 2; } return(Math.Max(1, compressionRatio)); }
public void Initilize() { CLCase clModel = CommonDataManager.GetCLCase(base.LocalID); List <UIClass> classes = new List <UIClass>(); clModel.Courses.ForEach(c => { var values = clModel.GetClasses(c.ID); foreach (var v in values) { v.NO = ++_no; classes.Add(v); } }); this.Classes = classes; }
/// <summary> /// 获取节次 /// </summary> /// <param name="cl"></param> /// <returns></returns> public static List <DayPeriodModel> GetDayPeriods(this CLCase cl) { List <DayPeriodModel> dayPeriods = new List <DayPeriodModel>(); var positions = cl.Positions.Where(p => p.Position != XYKernel.OS.Common.Enums.Position.AB && p.Position != XYKernel.OS.Common.Enums.Position.PB && p.Position != XYKernel.OS.Common.Enums.Position.Noon); if (positions != null) { var groups = positions.GroupBy(p => p.DayPeriod.PeriodName); foreach (var g in groups) { dayPeriods.Add(g.First().DayPeriod); } } return(dayPeriods); }
/// <summary> /// 获取课时根据课程ID /// </summary> /// <param name="cl"></param> /// <param name="courseID"></param> /// <param name="classID"></param> /// <returns></returns> public static List <UIClassHour> GetClassHours(this CLCase cl, string courseID, string classID, string levelID) { List <UIClassHour> results = new List <UIClassHour>(); var teachers = cl.Teachers; var classes = cl.Classes; var courses = cl.Courses; var classHours = cl.ClassHours.Where(c => c.CourseID.Equals(courseID) && c.ClassID.Equals(classID) && c.LevelID.Equals(levelID)); foreach (var ch in classHours) { UIClassHour uiClassHour = new UIClassHour(); uiClassHour.ClassID = ch.ClassID; uiClassHour.CourseID = ch.CourseID; uiClassHour.LevelID = ch.LevelID; uiClassHour.ID = ch.ID; if (ch.TeacherIDs == null) { uiClassHour.Teachers = new List <TeacherModel>(); } else { uiClassHour.Teachers = (from id in ch.TeacherIDs from t in teachers where t.ID == id select t)?.ToList(); } uiClassHour.Class = classes.FirstOrDefault(c => c.ID.Equals(ch.ClassID))?.Name; var course = courses.FirstOrDefault(c => c.ID.Equals(ch.CourseID)); uiClassHour.Course = course?.Name; if (course != null) { uiClassHour.Level = course.Levels?.FirstOrDefault(l => l.ID.Equals(ch.LevelID))?.Name; } results.Add(uiClassHour); } return(results); }
public void BindData(List <UIStudent> students, CLCase cl) { foreach (var student in students) { IDictionary <string, object> dics = new ExpandoObject(); cl.Courses.ForEach(c => { dics.Add(c.Name, string.Empty); }); student.Preselections.ForEach(p => { // 列头显示情况。 var hasColumn = dics.ContainsKey(p.Course); if (hasColumn) { if (!p.LevelID.Equals("0")) { dics[p.Course] = p.Level; } else { var has = dics.ContainsKey(p.Course); if (has) { dics[p.Course] = p.Course; } } } }); var firstStudent = this.Students.FirstOrDefault(s => s.ID.Equals(student.ID)); if (firstStudent != null) { firstStudent.ExpandoObject = dics; } } }
/// <summary> /// 学生抽样,仅根据设定保留部分学生 /// </summary> /// <param name="cLCase"></param> /// <param name="rule"></param> /// <param name="algoRule"></param> /// <param name="studentExtractionModel"></param> /// <returns></returns> public Tuple <CLCase, bool, List <DataValidationResultInfo> > GetModelByStudentExtraction(CLCase cLCase, Rule rule, AlgoRule algoRule, StudentExtractionModel studentExtractionModel) { List <DataValidationResultInfo> mydvri = new List <DataValidationResultInfo>() { }; bool checkResult = ModelValidation.ValidateModel(cLCase, algoRule, rule, out mydvri); if (!checkResult) { return(Tuple.Create(cLCase, false, mydvri)); } if (cLCase != null && studentExtractionModel != null) { //update Positions if (studentExtractionModel.Positions != null) { cLCase.Positions = studentExtractionModel.Positions; } //remove combination if (studentExtractionModel.RemovedCombination != null) { cLCase = Utility.GetCaseByRemovedCombination(cLCase, studentExtractionModel.RemovedCombination); } if (studentExtractionModel.ExtractionRatio >= 1 && studentExtractionModel.ExtractionRatio <= 100) { cLCase = Utility.GetCaseByExtractionRatio(cLCase, studentExtractionModel.ExtractionRatio); } //Increase Capacity if (studentExtractionModel.IncreasedCapacity > 0) { cLCase.Classes?.ForEach(x => { x.Capacity = x.Capacity + studentExtractionModel.IncreasedCapacity; }); } } return(Tuple.Create(cLCase, true, mydvri)); }
/// <summary> /// 抽样排课后的优化步骤 /// </summary> /// <param name="cLCase"></param> /// <param name="algoRule"></param> /// <param name="normalModel"></param> /// <param name="resultModel"></param> /// <param name="IncreasedCapacity"></param> /// <returns></returns> public Tuple <CLCase, AlgoRule, bool, List <DataValidationResultInfo> > GetModelByFixedClassTimeTable(CLCase cLCase, Rule rule, AlgoRule algoRule, NormalModel normalModel, ResultModel resultModel, int IncreasedCapacity) { List <DataValidationResultInfo> mydvri = new List <DataValidationResultInfo>() { }; bool checkResult = ModelValidation.ValidateModel(cLCase, algoRule, rule, out mydvri); if (!checkResult) { return(Tuple.Create(cLCase, algoRule, false, mydvri)); } if (cLCase != null && resultModel != null) { //remove selected combinations if (normalModel?.RemovedCombination != null) { cLCase = Utility.GetCaseByRemovedCombination(cLCase, normalModel.RemovedCombination); } //Update Capacity if (normalModel?.ClassCapacity != null) { normalModel.ClassCapacity.ForEach(x => { cLCase?.Classes?.Where(c => c.ID == x.ClassId)?.ToList()?.ForEach(c => { c.Capacity = c.Capacity + x.Capacity; }); }); } if (IncreasedCapacity > 0) { cLCase?.Classes?.ForEach(x => { x.Capacity = x.Capacity + IncreasedCapacity; }); } //Update Positions if (normalModel?.Positions != null) { cLCase.Positions = normalModel.Positions; } //Analysis ResultModel and add rule to algoRule if (resultModel.ResultClasses != null) { if (algoRule == null) { algoRule = new AlgoRule(); } if (algoRule.ClassHourRequiredStartingTime == null) { algoRule.ClassHourRequiredStartingTime = new List <ClassHourRequiredStartingTimeRule>() { }; } resultModel.ResultClasses?.ToList()?.ForEach(x => { x.ResultDetails?.ToList()?.ForEach(rd => { algoRule.ClassHourRequiredStartingTime.Add(new ClassHourRequiredStartingTimeRule() { ID = rd.ClassHourId, Period = rd.DayPeriod, Weight = 100 }); }); }); } } return(Tuple.Create(cLCase, algoRule, true, mydvri)); }
/// <summary> /// 仅排教师 /// </summary> /// <param name="cLCase"></param> /// <param name="rule"></param> /// <param name="algoRule"></param> /// <returns></returns> public Tuple <CLCase, bool, List <DataValidationResultInfo> > GetModelWithoutStudents(CLCase cLCase, Rule rule, AlgoRule algoRule) { List <DataValidationResultInfo> mydvri = new List <DataValidationResultInfo>() { }; bool checkResult = ModelValidation.ValidateModel(cLCase, algoRule, rule, out mydvri); if (!checkResult) { return(Tuple.Create(cLCase, false, mydvri)); } try { //remove all students cLCase?.Students?.Clear(); cLCase?.Classes?.ForEach(x => { x.StudentIDs.Clear(); }); } catch (Exception ex) { ErrorMessage = ex.Message; } return(Tuple.Create(cLCase, true, mydvri)); }
/// <summary> /// 仅排教师和分到班的学生,删除所有班级未固定的学生 /// </summary> /// <param name="cLCase"></param> /// <param name="rule"></param> /// <param name="algoRule"></param> /// <returns></returns> public Tuple <CLCase, bool, List <DataValidationResultInfo> > GetModelWithOnlyStudentsAssignedToClass(CLCase cLCase, Rule rule, AlgoRule algoRule) { List <DataValidationResultInfo> mydvri = new List <DataValidationResultInfo>() { }; bool checkResult = ModelValidation.ValidateModel(cLCase, algoRule, rule, out mydvri); if (!checkResult) { return(Tuple.Create(cLCase, false, mydvri)); } //仅排教师和分到班的学生,删除所有班级未固定的学生 cLCase?.Courses?.ForEach(x => { x.Levels?.ForEach(le => { int classNumber = cLCase?.Classes?.Where(c => c.CourseID == x.ID && c.LevelID == le.ID)?.ToList()?.Count ?? 0; if (classNumber > 1) { cLCase?.Students?.ForEach(s => { s.Preselections.RemoveAll(p => p.CourseID == x.ID && p.LevelID == le.ID); }); } }); }); return(Tuple.Create(cLCase, true, mydvri)); }
/// <summary> /// 课位压缩,根据设定参数压缩课位 /// </summary> /// <param name="cLCase"></param> /// <param name="rule"></param> /// <param name="algoRule"></param> /// <param name="timeCompressionModel"></param> /// <returns></returns> public Tuple <CLCase, Rule, AlgoRule, bool, List <DataValidationResultInfo> > GetModelByTimeCompression(CLCase cLCase, Rule rule, AlgoRule algoRule, TimeCompressionModel timeCompressionModel) { List <DataValidationResultInfo> mydvri = new List <DataValidationResultInfo>() { }; bool checkResult = ModelValidation.ValidateModel(cLCase, algoRule, rule, out mydvri); if (!checkResult) { return(Tuple.Create(cLCase, rule, algoRule, false, mydvri)); } if (cLCase != null && timeCompressionModel != null) { if (timeCompressionModel.ClassCapacity != null) { timeCompressionModel.ClassCapacity.ForEach(x => { cLCase?.Classes?.Where(c => c.ID == x.ClassId)?.ToList()?.ForEach(c => { c.Capacity = x.Capacity; }); }); } if (timeCompressionModel.RemovedCombination != null) { cLCase = Utility.GetCaseByRemovedCombination(cLCase, timeCompressionModel.RemovedCombination); } if (timeCompressionModel.CompressionRatio > 1) { //调整课时 cLCase = Utility.GetCaseClassHourUpdateByTimeCompressionRatio(cLCase, timeCompressionModel.CompressionRatio); //调整课位 Tuple <CLCase, AlgoRule> cLCaseAndAlgoRule = Utility.GetCasePositionsUpdateByTimeCompressionRatio(cLCase, algoRule, timeCompressionModel.CompressionRatio); cLCase = cLCaseAndAlgoRule.Item1; algoRule = cLCaseAndAlgoRule.Item2; //Add Tags if (cLCase.Tags == null) { cLCase.Tags = new List <TagModel>(); } if (!cLCase.Tags.Exists(t => t.ID == SystemTag.XYTagN.ToString())) { cLCase.Tags.Add(new TagModel() { ID = SystemTag.XYTagN.ToString(), Name = SystemTag.XYTagN.ToString() }); } if (!cLCase.Tags.Exists(t => t.ID == SystemTag.XYTag1.ToString())) { cLCase.Tags.Add(new TagModel() { ID = SystemTag.XYTag1.ToString(), Name = SystemTag.XYTag1.ToString() }); } } } return(Tuple.Create(cLCase, new Rule() { }, algoRule, true, mydvri)); }
public void Initilize() { CLCase clModel = CommonDataManager.GetCLCase(base.LocalID); var results = new List <UITwoStatusWeek>(); var groups = clModel.Positions.GroupBy(p => p.DayPeriod.Period); if (groups != null) { foreach (var g in groups) { var first = g.First(); UITwoStatusWeek week = new UITwoStatusWeek() { Period = first.DayPeriod, PositionType = first.Position, }; week.SetStatus(true); if (first.Position != XYKernel.OS.Common.Enums.Position.AB && first.Position != XYKernel.OS.Common.Enums.Position.PB && first.Position != XYKernel.OS.Common.Enums.Position.Noon) { g.ToList().ForEach(gg => { if (gg.DayPeriod.Day == DayOfWeek.Monday) { week.Monday.IsChecked = gg.IsSelected; } else if (gg.DayPeriod.Day == DayOfWeek.Tuesday) { week.Tuesday.IsChecked = gg.IsSelected; } else if (gg.DayPeriod.Day == DayOfWeek.Wednesday) { week.Wednesday.IsChecked = gg.IsSelected; } else if (gg.DayPeriod.Day == DayOfWeek.Thursday) { week.Thursday.IsChecked = gg.IsSelected; } else if (gg.DayPeriod.Day == DayOfWeek.Friday) { week.Friday.IsChecked = gg.IsSelected; } else if (gg.DayPeriod.Day == DayOfWeek.Saturday) { week.Saturday.IsChecked = gg.IsSelected; } else if (gg.DayPeriod.Day == DayOfWeek.Sunday) { week.Sunday.IsChecked = gg.IsSelected; } }); } results.Add(week); } } this.Periods = results; }
public void Initilize() { CLCase caseModel = CommonDataManager.GetCLCase(base.LocalID); var courseLevels = (from c in caseModel.Courses from cl in c.Levels select new { CourseID = c.ID, Course = c.Name, LevelID = cl.ID, Level = cl.Name, Display = $"{c.Name}|{cl.Name}" }); var groups = caseModel.Students.GroupBy(s => { return((from sp in s.Preselections from cl in courseLevels where cl.LevelID.Equals(sp.LevelID) && cl.CourseID.Equals(sp.CourseID) select new { display = $"{cl.Course}{cl.Level}" }).OrderBy(d => d.display).Select(d => d.display).Parse()); }); if (groups != null) { List <UICombination> combinations = new List <UICombination>(); int no = 0; foreach (var g in groups) { if (g.All(gg => gg.Preselections.Count == 0)) { continue; } UICombination combination = new UICombination(); combination.NO = ++no; combination.Combination = g.Key; combination.Students = g.Count(); var selection = g.First(); combination.Selections = selection.Preselections.Select(sp => { return(new XYKernel.OS.Common.Models.Pattern.Extend.SelectionModel() { CourseId = sp.CourseID, LevelId = sp.LevelID }); })?.ToList(); combinations.Add(combination); } ; // 绑定去除组合 this.Combinations = combinations; } }
public static Tuple <CLCase, AlgoRule> GetCasePositionsUpdateByTimeCompressionRatio(CLCase cLCase, AlgoRule algoRule, int CompressionRatio) { List <TeacherTagClassHour> teacherTagClassHour = new List <TeacherTagClassHour>(); List <StudentTagClassHour> studentTagClassHour = new List <StudentTagClassHour>(); List <StudentTagClassHour> studentTagClassHourBK = new List <StudentTagClassHour>(); //统计教师的课时(压缩与非压缩) cLCase.Teachers.ForEach(x => { cLCase.ClassHours?.Where(c => c.TeacherIDs != null && c.TagIDs != null && c.TeacherIDs.Contains(x.ID)) ?.Select(c => new { TeacherId = x.ID, Tags = c.TagIDs, c.ClassID }) ?.ToList()?.ForEach(c => { if (c.Tags.Contains(SystemTag.XYTagN.ToString())) { teacherTagClassHour.Add(new TeacherTagClassHour() { ClassID = c.ClassID, TagType = SystemTag.XYTagN.ToString(), TeacherId = x.ID }); } else if (c.Tags.Contains(SystemTag.XYTag1.ToString())) { teacherTagClassHour.Add(new TeacherTagClassHour() { ClassID = c.ClassID, TagType = SystemTag.XYTag1.ToString(), TeacherId = x.ID }); } }); }); //统计学生的课时(压缩与非压缩) cLCase.Students?.ForEach(x => { x.Preselections.ForEach(s => { studentTagClassHourBK.Add(new StudentTagClassHour() { StudentId = x.ID, CourseID = s.CourseID, LevelID = s.LevelID, TagType = "" }); }); }); cLCase.Courses.ForEach(co => { co.Levels.ForEach(le => { ClassModel classInfo = cLCase.Classes.FirstOrDefault(cl => cl.CourseID == co.ID && cl.LevelID == le.ID); if (classInfo != null) { string ClassID = cLCase.Classes.First(cl => cl.CourseID == co.ID && cl.LevelID == le.ID).ID; var classHours = cLCase.ClassHours.Where(c => c.ClassID == ClassID); int tagNCount = classHours.Where(x => x.TagIDs != null && x.TagIDs.Contains(SystemTag.XYTagN.ToString())).Count(); int tag1Count = classHours.Where(x => x.TagIDs != null && x.TagIDs.Contains(SystemTag.XYTag1.ToString())).Count(); for (int i = 0; i < tagNCount; i++) { studentTagClassHourBK.Where(x => x.CourseID == co.ID && x.LevelID == le.ID).ToList().ForEach(x => { studentTagClassHour.Add(new StudentTagClassHour() { StudentId = x.StudentId, CourseID = x.CourseID, LevelID = x.LevelID, TagType = SystemTag.XYTagN.ToString() }); }); } for (int i = 0; i < tag1Count; i++) { studentTagClassHourBK.Where(x => x.CourseID == co.ID && x.LevelID == le.ID).ToList().ForEach(x => { studentTagClassHour.Add(new StudentTagClassHour() { StudentId = x.StudentId, CourseID = x.CourseID, LevelID = x.LevelID, TagType = SystemTag.XYTag1.ToString() }); }); } } }); }); //如果班级都没有安排教师,且没有学生怎么办: 按照教学班统计最大课时 var noTS = cLCase.ClassHours.Where(x => (x.TeacherIDs == null || x.TeacherIDs.Count == 0)); int noTSMaxN = 0; if (noTS.Where(x => x.TagIDs != null && x.TagIDs.Contains(SystemTag.XYTagN.ToString())).Any()) { noTSMaxN = noTS.Where(x => x.TagIDs != null && x.TagIDs.Contains(SystemTag.XYTagN.ToString())) .Select(x => new { x.ClassID }) .GroupBy(x => new { x.ClassID }) .Select(x => new { x.Key.ClassID, Count = x.Count() }).Max(x => x.Count); } int noTSMax1 = 0; if (noTS.Where(x => x.TagIDs != null && x.TagIDs.Contains(SystemTag.XYTag1.ToString())).Any()) { noTSMax1 = noTS.Where(x => x.TagIDs != null && x.TagIDs.Contains(SystemTag.XYTag1.ToString())) .Select(x => new { x.ClassID }) .GroupBy(x => new { x.ClassID }) .Select(x => new { x.Key.ClassID, Count = x.Count() }).Max(x => x.Count); } //计算需要最大的压缩课位和非压缩课位 int teacherMaxN = 0; if (teacherTagClassHour.Where(x => x.TagType == SystemTag.XYTagN.ToString()).Any()) { teacherMaxN = teacherTagClassHour.Where(x => x.TagType == SystemTag.XYTagN.ToString()) .GroupBy(x => new { x.TeacherId, x.TagType }) .Select(x => new { x.Key.TeacherId, x.Key.TagType, Count = x.Count() }).Max(x => x.Count); } int teacherMax1 = 0; if (teacherTagClassHour.Where(x => x.TagType == SystemTag.XYTag1.ToString()).Any()) { teacherMax1 = teacherTagClassHour.Where(x => x.TagType == SystemTag.XYTag1.ToString()) .GroupBy(x => new { x.TeacherId, x.TagType }) .Select(x => new { x.Key.TeacherId, x.Key.TagType, Count = x.Count() }).Max(x => x.Count); } //计算需要最大的压缩课位和非压缩课位 int studentMaxN = 0; if (studentTagClassHour.Where(x => x.TagType == SystemTag.XYTagN.ToString()).Any()) { studentMaxN = studentTagClassHour.Where(x => x.TagType == SystemTag.XYTagN.ToString()) .GroupBy(x => new { x.StudentId, x.TagType }) .Select(x => new { x.Key.StudentId, x.Key.TagType, Count = x.Count() }).Max(x => x.Count); } int studentMax1 = 0; if (studentTagClassHour.Where(x => x.TagType == SystemTag.XYTag1.ToString()).Any()) { studentMax1 = studentTagClassHour.Where(x => x.TagType == SystemTag.XYTag1.ToString()) .GroupBy(x => new { x.StudentId, x.TagType }) .Select(x => new { x.Key.StudentId, x.Key.TagType, Count = x.Count() }).Max(x => x.Count); } int TSmaxN = Math.Max(teacherMaxN, studentMaxN); int TSmax1 = Math.Max(teacherMax1, studentMax1); int maxN = Math.Max(noTSMaxN, TSmaxN); int max1 = Math.Max(noTSMax1, TSmax1); //初始化课位 cLCase.Positions.ForEach(x => { x.IsSelected = false; }); //设定新的排课课位 //TagN TimeSlot ClassHoursRequiredTimesRule tagNRules = new ClassHoursRequiredTimesRule(); tagNRules.Times = new List <XYKernel.OS.Common.Models.DayPeriodModel>(); tagNRules.Active = true; tagNRules.Weight = 100; tagNRules.TagID = SystemTag.XYTagN.ToString(); for (int i = 0; i < maxN; i++) { var coursePosition = cLCase.Positions.Where(x => x.IsSelected == false && x.Position != Position.AB && x.Position != Position.Noon && x.Position != Position.PB && x.DayPeriod.Day > 0) .OrderBy(x => x.DayPeriod.Day).ThenBy(x => x.DayPeriod.Period).First(); coursePosition.IsSelected = true; tagNRules.Times.Add(coursePosition.DayPeriod); } //Tag1 TimeSlot ClassHoursRequiredTimesRule tag1Rules = new ClassHoursRequiredTimesRule(); tag1Rules.Times = new List <XYKernel.OS.Common.Models.DayPeriodModel>(); tag1Rules.Active = true; tag1Rules.Weight = 100; tag1Rules.TagID = SystemTag.XYTag1.ToString(); for (int i = 0; i < max1; i++) { var coursePosition = cLCase.Positions.Where(x => x.IsSelected == false && x.Position != Position.AB && x.Position != Position.Noon && x.Position != Position.PB && x.DayPeriod.Day == 0) .OrderBy(x => x.DayPeriod.Day).ThenBy(x => x.DayPeriod.Period).FirstOrDefault(); if (coursePosition == null) { coursePosition = cLCase.Positions.Where(x => x.IsSelected == false && x.Position != Position.AB && x.Position != Position.Noon && x.Position != Position.PB && x.DayPeriod.Day > 0) .OrderByDescending(x => x.DayPeriod.Day).ThenBy(x => x.DayPeriod.Period).FirstOrDefault(); } if (coursePosition != null) { coursePosition.IsSelected = true; tag1Rules.Times.Add(coursePosition.DayPeriod); } } //将两种时间分别记录到规则中,形成约束 algoRule = new AlgoRule(); if (algoRule.ClassHoursRequiredTimes == null) { algoRule.ClassHoursRequiredTimes = new List <ClassHoursRequiredTimesRule>(); } if (tag1Rules.Times.Count > 0) { algoRule.ClassHoursRequiredTimes.Add(tag1Rules); } if (tagNRules.Times.Count > 0) { algoRule.ClassHoursRequiredTimes.Add(tagNRules); } return(Tuple.Create(cLCase, algoRule)); }
/// <summary> /// 常规排课模式 /// </summary> /// <param name="cLCase"></param> /// <param name="rule"></param> /// <param name="algoRule"></param> /// <param name="normalModel"></param> /// <returns></returns> public Tuple <CLCase, bool, List <DataValidationResultInfo> > GetModelByNormal(CLCase cLCase, Rule rule, AlgoRule algoRule, NormalModel normalModel) { List <DataValidationResultInfo> mydvri = new List <DataValidationResultInfo>() { }; bool checkResult = ModelValidation.ValidateModel(cLCase, algoRule, rule, out mydvri); if (!checkResult) { return(Tuple.Create(cLCase, false, mydvri)); } if (cLCase != null && normalModel != null) { //remove selected combinations if (normalModel.RemovedCombination != null) { cLCase = Utility.GetCaseByRemovedCombination(cLCase, normalModel.RemovedCombination); } //Update Capacity if (normalModel.ClassCapacity != null) { normalModel.ClassCapacity.ForEach(x => { cLCase?.Classes?.Where(c => c.ID == x.ClassId)?.ToList()?.ForEach(c => { c.Capacity = x.Capacity; }); }); } //Update Positions if (normalModel.Positions != null) { cLCase.Positions = normalModel.Positions; } } return(Tuple.Create(cLCase, true, mydvri)); }
/// <summary> /// 课位压缩排课后的优化步骤 /// </summary> /// <param name="cLCase"></param> /// <param name="rule"></param> /// <param name="algoRule"></param> /// <param name="resultModel"></param> /// <returns></returns> public Tuple <CLCase, Rule, AlgoRule, bool, List <DataValidationResultInfo> > GetModelByStudentsClassificationResult(CLCase cLCase, Rule rule, AlgoRule algoRule, ResultModel resultModel) { List <DataValidationResultInfo> mydvri = new List <DataValidationResultInfo>() { }; bool checkResult = ModelValidation.ValidateModel(cLCase, algoRule, rule, out mydvri); if (!checkResult) { return(Tuple.Create(cLCase, rule, algoRule, false, mydvri)); } if (cLCase != null && resultModel != null) { resultModel.ResultClasses?.ToList()?.ForEach(x => { var targetClass = cLCase.Classes?.FirstOrDefault(c => c.ID == x.ClassID); if (targetClass != null) { if (targetClass.StudentIDs == null) { targetClass.StudentIDs = (x.ResultStudents?.ToList() ?? new List <string>()); } else { targetClass.StudentIDs.AddRange(x.ResultStudents?.ToList() ?? new List <string>()); } } }); } //Check And add some rules if it's a auto schedule if (cLCase.IsAuto) { // } return(Tuple.Create(cLCase, rule, algoRule, true, mydvri)); }
/// <summary> /// 根据教师ID集合 /// </summary> /// <param name="cl">方案模型</param> /// <param name="teacherIDs">教师ID集合</param> /// <returns></returns> public static List <TeacherModel> GetTeachersByIds(this CLCase cl, List <string> teacherIDs) { return((from tid in teacherIDs from t in cl.Teachers where t.ID.Equals(tid) select t)?.ToList()); }
public static void TeacherChanged(Models.Base.UITeacher teacher, string localID, Rule rule, AlgoRule algo, CLCase cl, bool hasPatern) { if (cl != null) { cl.Classes?.ForEach(c => { c.TeacherIDs?.RemoveAll(t => t.Contains(teacher.ID)); }); cl.ClassHours?.ForEach(ch => { ch.TeacherIDs?.RemoveAll(t => t.Contains(teacher.ID)); }); if (hasPatern) { cl.SerializePatternCase(localID); } else { cl.Serialize(localID); } } if (rule != null) { rule.TeacherTimes?.RemoveAll(t => t.TeacherID.Contains(teacher.ID)); rule.MaxGapsPerDay?.RemoveAll(t => t.TeacherID.Contains(teacher.ID)); rule.MaxDaysPerWeek?.RemoveAll(t => t.TeacherID.Contains(teacher.ID)); rule.MaxHoursDaily?.RemoveAll(t => t.TeacherID.Contains(teacher.ID)); if (hasPatern) { rule.SerializePatternRule(localID); } else { rule.Serialize(localID); } } if (algo != null) { algo.TeacherMaxGapsPerDays?.RemoveAll(t => t.TeacherID.Equals(teacher.ID)); algo.TeacherMaxHoursDailys?.RemoveAll(t => t.TeacherID.Equals(teacher.ID)); algo.TeacherMaxDaysPerWeeks?.RemoveAll(t => t.TeacherID.Equals(teacher.ID)); algo.TeacherNotAvailableTimes?.RemoveAll(t => t.TeacherID.Equals(teacher.ID)); if (hasPatern) { algo.SerializePatternAlgo(localID); } else { algo.Serialize(localID); } } }