| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 | using System;using System.Collections.Generic;using System.Linq;namespace mxdemo.Mind{    #region models    /// <summary>    /// 选科组合    /// </summary>    public class SubjectGroup    {        public int Limitation { get; set; } // 人数限制        public string Name { get; set; }        public string Code { get; set; }        public long Id { get; set; }    }    /// <summary>    /// 志愿    /// </summary>    public class Preference    {        public int Rank { get; set; } // 第1、2、3志原 越小优先级越高        public long GroupId {get;set;}        public long StudentId { get; set; }        public long Id { get; set; }    }    /// <summary>    /// 得分情况    /// </summary>    public class GroupScore    {        public decimal Score { get; set; }        public long StudentId { get; set; }        public long GroupId { get; set; }    }    /// <summary>    /// 学生信息    /// </summary>    public class Student    {        public long Id { get; set; }        public string No { get; set; }        public string Name { get; set; }    }    public class ElectiveElement    {        public Student Student { get; set; }        public Preference Preference { get; set; }        public SubjectGroup Group { get; set; }        // 计算属性        public int PreferenceRank { get; set; } // 志愿排名        public int GroupRank { get; set; }  // 组合排名,即成绩排名(组合全校排名),同样越小优先级越高    }    #endregion    public class ElectiveResult    {        public ElectiveResult(List<Student> students)        {            this.UnmatchedStudents = students;        }        public List<Student> MatchedStudents { get; set; }            = new List<Student>();        public Dictionary<SubjectGroup, List<ElectiveElement>> MatchedDetails { get; set; }            = new Dictionary<SubjectGroup, List<ElectiveElement>>();        public List<Student> UnmatchedStudents { get; set; }        public void AppendMatched(ElectiveElement element)        {            // 应该还有更多细节需要考虑            var appendStudent = element.Student;            if (MatchedStudents.Contains(appendStudent)) return;            if (UnmatchedStudents.Contains(appendStudent))                RemoveUnmatched(appendStudent);            var appendGroup = MatchedDetails.ContainsKey(element.Group)                ? MatchedDetails[element.Group]                : new List<ElectiveElement>();            if (appendGroup.Count < element.Group.Limitation)            {                MatchedDetails[element.Group] = appendGroup;                AddMatchedAndDetails(element);            }            else            {                AddUnmatched(appendStudent);            }        }        private void AddMatchedAndDetails(ElectiveElement element)        {            // 应该还有更多细节需要考虑            MatchedDetails[element.Group].Add(element);            MatchedStudents.Add(element.Student);        }        private void AddUnmatched(Student student)        {            // 应该还有更多细节需要考虑            UnmatchedStudents.Add(student);        }        private void RemoveUnmatched(Student student)        {            // 应该还有更多细节需要考虑            UnmatchedStudents.Remove(student);        }    }    public interface IElectiveStrategy    {        /// <summary>        /// 从开放选科中取出按优先级分组的选科        /// </summary>        /// <returns></returns>        List<List<SubjectGroup>> GetAllPrioritizedGroups();        /// <summary>        /// 参与这次运算的志愿优先级集合        /// </summary>        /// <returns></returns>        List<List<int>> GetAllPrioritizedPreferenceRanks();        /// <summary>        /// 参与这次运算的所有学生        /// </summary>        /// <returns></returns>        List<Student> GetAllStudents();    }    public abstract class ElectiveEngine: IComparer<ElectiveElement>    {         protected IElectiveStrategy ElectiveStrategy { get; set; }        protected ElectiveEngine(IElectiveStrategy electiveStrategy)        {            ElectiveStrategy = electiveStrategy;        }        public ElectiveResult Execute()        {            var prioritizedGroups = ElectiveStrategy.GetAllPrioritizedGroups();            var prioritizedPreferenceRanks = ElectiveStrategy.GetAllPrioritizedPreferenceRanks();            var allStudents = ElectiveStrategy.GetAllStudents();            var electiveResult = new ElectiveResult(allStudents);            foreach(var groups in prioritizedGroups)            {                foreach(var ranks in prioritizedPreferenceRanks)                {                    var students = electiveResult.UnmatchedStudents;                    var elements = BuildElectiveElements(students, groups, ranks);                    ExecuteCore(elements, electiveResult);                }            }            return electiveResult;        }        private void ExecuteCore(List<ElectiveElement> elements, ElectiveResult context)        {            // 核心方法优先级排序, 已经按期望排好了录取顺序            elements.Sort(this);  // this.IComparer<ElectiveElement>.Compare            // 接下来考虑每个组合容量的问题            foreach(var element in elements)            {                context.AppendMatched(element);            }        }        protected virtual List<ElectiveElement> BuildElectiveElements(List<Student> students, List<SubjectGroup> groups, List<int> ranks)        {            // 根据组合与志愿 生成不同的选科元素            // 可以按计算需要,相互挂一些引用,方便计算过程中的删除操作            // TODO: 如果引入意向专业,也可以改写这个生成的逻辑            throw new NotImplementedException();        }        /// <summary>        /// 优先级比较        /// </summary>        /// <param name="x"></param>        /// <param name="y"></param>        /// <returns></returns>        public abstract int Compare(ElectiveElement x, ElectiveElement y);    }    public class PreferenceAheadElectiveEngine : ElectiveEngine    {        public PreferenceAheadElectiveEngine(IElectiveStrategy electiveStrategy)            :base(electiveStrategy)        {        }        public override int Compare(ElectiveElement x, ElectiveElement y)        {            // TODO: 容错处理            if (x.PreferenceRank == y.PreferenceRank) return y.GroupRank - x.GroupRank;            return y.PreferenceRank - x.PreferenceRank;        }    }    public class ScoreAheadElectiveEngine : ElectiveEngine    {        public ScoreAheadElectiveEngine(IElectiveStrategy electiveStrategy)            : base(electiveStrategy)        {        }        public override int Compare(ElectiveElement x, ElectiveElement y)        {            // TODO: 容错处理            if (x.GroupRank == y.GroupRank) return y.PreferenceRank - x.PreferenceRank;            return y.GroupRank - x.GroupRank;        }    }}
 |