Example #1
0
        /// <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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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);
        }
Example #5
0
        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);
        }
Example #7
0
 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);
            }
        }
Example #10
0
 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);
        }
Example #12
0
        /// <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;
        }
Example #16
0
        /// <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);
        }
Example #17
0
        /// <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));
        }
Example #29
0
 /// <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);
                }
            }
        }