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;
- }
- }
- }
|