private void ToCommonState(VcTime focuseTime) { EnLsnAct Act = null; DtMatrix <eRule> rles = VC2WinFmApp.Engine.GetSqdRule(this.squad); foreach (SqdScheduleCell cell in Matrix.eachCell()) { if (cell.Time == focuseTime) { cell.CellState = eCellState.focused; Act = cell.Act; } else { cell.CellState = eCellState.common; } cell.Rule = rles[cell.Time]; } RenewRuleGrid(focuseTime); schState = eSchState.common; if (Act == null || Act.ClsLesson == null) { VC2WinFmApp.MessageSwitch.SetLastTch(null, null); } else { VC2WinFmApp.MessageSwitch.SetLastTch(Act.ClsLesson.Teacher, Act.Time); } }
public T this[VcTime time] { get { return(Cells[time]); } }
private void ToInDropState(EnLsnAct Act, VcTime sTime) { DtMatrix <eRule> rles = VC2WinFmApp.Engine.GetActChangeRule(this.squad, Act, sTime); foreach (SqdScheduleCell cell in Matrix.eachCell()) { //存在重复更新,为简化逻辑,不要管 if (cell.Time == sTime) { cell.CellState = eCellState.isDropSrc; } else if (cell.Act != null && cell.Act.ClsLesson == Act.ClsLesson) { cell.CellState = eCellState.likeDropSrc; } else { cell.CellState = eCellState.inDrop; cell.Rule = rles[cell.Time]; } } RenewRuleGrid(sTime); sTime.CopyFieldTo(DropSrcTime); schState = eSchState.inDrop; //进入拖放状态 if (Act == null || Act.ClsLesson == null) { VC2WinFmApp.MessageSwitch.SetLastTch(null, null); } else { VC2WinFmApp.MessageSwitch.SetLastTch(Act.ClsLesson.Teacher, Act.Time); } }
public MatterCell this[VcTime time] { get { return(mattes[time]); } }
public void SetLastTch(EnTeacher tch, VcTime time) { if (VC2WinFmApp.TopFm != null && !VC2WinFmApp.TopFm.IsDisposed) { VC2WinFmApp.TopFm.LastTch = tch; VC2WinFmApp.TopFm.LastTime = time; } }
/// <summary> /// 迭代全校某时间的课 /// </summary> private IEnumerable <ScheduleNode> eachEnabledScheduleNode(VcTime time) { foreach (SqdSchedule sqdSch in SqdScheduleList.Values) { if (sqdSch.Matrix[time].LsnAct != null) { yield return(sqdSch.Matrix[time]); } } }
public eRule GetRuleOfTime(BaseEntity Ety, VcTime time) { foreach (VcRuleCell rt in GetRules(Ety)) { if (rt.Time == time) { return(rt.Rule); } } return(eRule.common); }
/// <summary> /// 获得当前虚拟态的课表某节的规则列表与冲突 /// </summary> public IList <VcActEtyRelation> GetSqdClash(EnSquad squad, VcTime time) { List <VcActEtyRelation> Result = new List <VcActEtyRelation>(); if (!this.TimeIsEnabled(time)) { return(Result); } //获得VcLsnAct EnLsnAct act = SqdScheduleList[squad].Matrix[time].LsnAct; if (act == null) { return(Result); } //添加授课教师 if (act.ClsLesson.Teacher != null) { Result.Add(new VcActEtyRelation(act.ClsLesson.Teacher, eActEtyRelation.teach)); //整理出冲突课程 foreach (SqdSchedule sch in SqdScheduleList.Values) { if (sch.Matrix[time].LsnAct != null && sch.Matrix[time].LsnAct.ClsLesson.Squad != squad && sch.Matrix[time].LsnAct.ClsLesson.Teacher == act.ClsLesson.Teacher) { Result.Add(new VcActEtyRelation(sch.Matrix[time].LsnAct.ClsLesson, eActEtyRelation.clash, eRule.crisscross)); } } } //添加Lsn/ClsLsn的Rule Result.Add(new VcActEtyRelation(act.ClsLesson.Lesson, eActEtyRelation.rule, DataRule.Rule.GetRuleOfTime(act.ClsLesson.Lesson, time))); Result.Add(new VcActEtyRelation(act.ClsLesson, eActEtyRelation.rule, DataRule.Rule.GetRuleOfTime(act.ClsLesson, time))); //迭代Act的元素,添加Rule foreach (BaseEntity ety in this.eachClsLsnComponent(act.ClsLesson)) { Result.Add(new VcActEtyRelation(ety, eActEtyRelation.rule, DataRule.Rule.GetRuleOfTime(ety, time))); } return(Result); }
/// <summary> /// 课表拖放后 /// </summary> public void Move(EnSquad squad, EnLsnAct sAct, VcTime tTime) { SqdSchedule sch = SqdScheduleList[squad]; //获得来源的act的时间sTime VcTime sTime = new VcTime(); if (!sch.FailLsnActs.Contains(sAct)) { foreach (VcTime tt in sch.Matrix.eachTime()) { if (sch.Matrix[tt].LsnAct == sAct) { tt.CopyFieldTo(sTime); break; } } } if (sTime == tTime) //原地拖 { return; } else if (sTime.HasValue && !tTime.HasValue) //从课表拖到FailLsnActs { EnLsnAct ta = sch.Matrix[sTime].LsnAct; sch.FailLsnActs.Add(ta); sch.Matrix[sTime].LsnAct = null; } else if (!sTime.HasValue && tTime.HasValue) //从FailLsnActs拖到课表 { if (sch.Matrix[tTime].LsnAct != null) { return; } sch.Matrix[tTime].LsnAct = sAct; sch.FailLsnActs.Remove(sAct); } else if (sTime.HasValue && tTime.HasValue) //课表拖到课表 { EnLsnAct ta = sch.Matrix[sTime].LsnAct; sch.Matrix[sTime].LsnAct = sch.Matrix[tTime].LsnAct; sch.Matrix[tTime].LsnAct = ta; } sch.Modified = true; this.Modified = true; this.AfterScheduleChanged(squad); }
private void thisDragDrop(object sender, DragEventArgs e) { EnLsnAct act = e.Data.GetData(typeof(EnLsnAct)) as EnLsnAct; VcTime tTime = new VcTime(); if (sender is SqdScheduleCell) { (sender as SqdScheduleCell).Time.CopyFieldTo(tTime); } //Move将触发更新,存在重复更新,为简化逻辑,不要管 ToCommonState(tTime); VC2WinFmApp.Engine.Move(this.squad, act, tTime); }
/// <summary> /// 低效操作,小心使用 /// </summary> public T this[VcTime time] { get { foreach (T t in eachCell()) { if (t.Time == time) { return(t); } } throw new Exception("无效的时间!"); } }
private void thisMouseMove(object sender, MouseEventArgs e) { CheckFocusTch(sender, e.Location); //取当前聚焦的 if (ReadOnly || (schState != eSchState.common && schState != eSchState.focused) || e.Button != MouseButtons.Left || schState == eSchState.inDrop) { return; } if (Math.Abs(e.X - DownXY.X) < 5 && Math.Abs(e.Y - DownXY.Y) < 5) { return; } EnLsnAct Act = null; VcTime sTime = new VcTime(); if (sender == TaskGrid && TaskGridBind.Count > 0) { DataGridView.HitTestInfo hi = TaskGrid.HitTest(e.X, e.Y); TaskGridBind.Position = hi.RowIndex; TaskGrid.Refresh(); //有用的,让TaskGrid更新当前选中行为被选中状态 Act = TaskGridBind.Current as EnLsnAct; } else if (sender is SqdScheduleCell) { Act = (sender as SqdScheduleCell).Act; (sender as SqdScheduleCell).Time.CopyFieldTo(sTime); } if (Act != null) { ToInDropState(Act, sTime); (sender as Control).DoDragDrop(Act, DragDropEffects.Move); } }
public void RefreshRule() { DtMatrix <eRule> rles = VC2WinFmApp.Engine.GetSqdRule(this.squad); foreach (VcTime time in rles.eachTime()) { Matrix[time].Rule = rles[time]; } VcTime focuseTime = new VcTime(); foreach (SqdScheduleCell cell in Matrix.eachCell()) { if (cell.CellState == eCellState.focused) { cell.Time.CopyFieldTo(focuseTime); } } RenewRuleGrid(focuseTime); }
private void RenewRuleGrid(VcTime focuseTime) { IList <VcActEtyRelation> clashRules = VC2WinFmApp.Engine.GetSqdClash(this.squad, focuseTime); IList <VcActEtyRelation> clashRules2 = new List <VcActEtyRelation>(); foreach (VcActEtyRelation rln in clashRules) { if (rln.Relation == eActEtyRelation.teach) { clashRules2.Add(rln); } } foreach (VcActEtyRelation rln in clashRules) { if (rln.Relation == eActEtyRelation.clash) { clashRules2.Add(rln); } } foreach (VcActEtyRelation rln in clashRules) { if (rln.Relation == eActEtyRelation.rule && rln.Rule == eRule.crisscross) { clashRules2.Add(rln); } } foreach (VcActEtyRelation rln in clashRules) { if (rln.Relation == eActEtyRelation.rule && rln.Rule != eRule.crisscross) { clashRules2.Add(rln); } } RuleGrid.DataSource = clashRules2; }
public Boolean TimeIsEnabled(VcTime time) { return(TimeTestMatrix.TestTime(time)); }
public EnFailAct(EnLsnAct act, VcTime time) { this.act = act; time.CopyFieldTo(this.time); }
/// <summary> /// 获取交换时优势 /// </summary> public DtMatrix <eRule> GetActChangeRule(EnSquad squad, EnLsnAct sAct, VcTime sTime) { Debug.Assert(sAct != null, "为简化程序逻辑,空课不可拖。"); //这个方法是本程序中最复杂的逻辑 //步骤: //一、获得所有位置当前优势 //二、获得sAct当前优势 //三、获得所有位置的Act移动到sTime的优势值 //四、获得sAct移动到所有位置的优势值 //五、比较当前优势和移动后的优势,获得交换的价值 SqdSchedule NowSch = SqdScheduleList[squad]; //一、获得所有位置当前优势 DtMatrix <eRule> NowRules = this.GetSqdRule(squad); //二、获得sAct当前优势 eRule sActNowRule; if (NowRules.TestTime(sTime)) { sActNowRule = NowRules[sTime]; } else { sActNowRule = eRule.common; //未排 } //三、获得所有位置的Act移动到sTime的优势值 DtMatrix <eRule> FutureRules = new DtMatrix <eRule>(DataRule.Solution); if (FutureRules.TestTime(sTime)) { IList <EnTeacher> sTimeTchs = new List <EnTeacher>(); foreach (SqdSchedule sch in this.SqdScheduleList.Values) { if (sch != NowSch && sch.Matrix[sTime].LsnAct != null) { EnLsnAct act = sch.Matrix[sTime].LsnAct; if (act.ClsLesson.Teacher != null && !sTimeTchs.Contains(act.ClsLesson.Teacher)) { sTimeTchs.Add(act.ClsLesson.Teacher); } } } foreach (VcTime time in FutureRules.eachTime()) { if (NowSch.Matrix[time].LsnAct != null) { EnLsnAct act = NowSch.Matrix[time].LsnAct; if (act.ClsLesson.Teacher != null && sTimeTchs.Contains(act.ClsLesson.Teacher)) { FutureRules[time] = eRule.crisscross; //此课程移到sTime后导致教师冲突 } else { FutureRules[time] = ClsLsnRuleList[act.ClsLesson][sTime]; //移到sTime后的优势 } } } } else { //所有Act移动到未排,则优势一定是eRule.common foreach (VcTime time in FutureRules.eachTime()) { FutureRules[time] = eRule.common; } } //四、获得sAct移动到所有位置的优势值 DtMatrix <eRule> sActFutureRules = new DtMatrix <eRule>(DataRule.Solution); DtMatrix <eRule> TmpRules = ClsLsnRuleList[sAct.ClsLesson]; foreach (VcTime time in TmpRules.eachTime()) { sActFutureRules[time] = TmpRules[time]; } //检测课程冲突 if (sAct.ClsLesson.Teacher != null) { EnTeacher NowTch = sAct.ClsLesson.Teacher; DtMatrix <IList <EnLsnAct> > sTchLsns = this.GetTchMatrix(NowTch); foreach (VcTime time in sTchLsns.eachTime()) { if (sTchLsns[time] != null && sTchLsns[time].Count > 0) { foreach (EnLsnAct act in sTchLsns[time]) { if (act != NowSch.Matrix[time].LsnAct && //当前课表的,会被移走 act.ClsLesson.Teacher == NowTch) { sActFutureRules[time] = eRule.crisscross; //sAct移到time后将导致冲突 break; } } } } } //五、比较当前优势和移动后的优势,获得交换的价值矩阵 DtMatrix <eRule> Result = new DtMatrix <eRule>(DataRule.Solution); //NowRules、sActNowRule、FutureRules、sActFutureRules //所有位置当前优势\拖动源当前优势\所有位置在拖动源的优势\拖动源拖到所有位置的优势 foreach (VcTime time in Result.eachTime()) { if (NowSch.Matrix[time].LsnAct != null && NowSch.Matrix[time].LsnAct.ClsLesson == sAct.ClsLesson) { Result[time] = eRule.crisscross; //同样的课移动没意义的 continue; } Result[time] = ComparerActChangeRule(NowRules[time], sActNowRule, FutureRules[time], sActFutureRules[time]); } return(Result); }
/// <summary> /// 仅负责把空课安排到合适的位置,不会动已排的课 /// </summary> private Boolean Automatic(EnSquad squad) { if (SqdScheduleList[squad].FailLsnActs.Count == 0) { return(false); } //策略: //第一步:整理FailLsnActs到有序(同VcClsLesson相邻,为提高速度) //对每一VcLsnAct:计算优势值(靠评价函数),安排到优势值最大的Time SqdSchedule sch = SqdScheduleList[squad]; sch.Modified = true; IList <EnLsnAct> OrderFailLsnActs = GetOrderFailLsnActs(sch.FailLsnActs); Int32 DaySum = 0; foreach (Boolean bl in DataRule.Solution.ActiveWeekArr) { if (bl) { DaySum++; } } EnClsLesson frontClsLsn = null; DtMatrix <Boolean> TchConcretes = null; DtMatrix <eRule> ClsLsnRules = null; Int32[] CourseCnt = new Int32[7]; Int32 CourseAverage = 0; foreach (EnLsnAct act in OrderFailLsnActs) { if (frontClsLsn == null || frontClsLsn != act.ClsLesson) { frontClsLsn = act.ClsLesson; TchConcretes = new DtMatrix <bool>(DataRule.Solution); ClsLsnRules = this.ClsLsnRuleList[act.ClsLesson]; if (act.ClsLesson.Teacher != null) { foreach (VcTime time in sch.Matrix.eachTime()) { if (sch.Matrix[time].LsnAct == null) { foreach (SqdSchedule sqdSch in SqdScheduleList.Values) { if (sqdSch.Matrix[time].LsnAct != null && sqdSch.Matrix[time].LsnAct.ClsLesson.Teacher == act.ClsLesson.Teacher) { TchConcretes[time] = true; break; } } } } } //foreach (Int32 cnt in CourseCnt) // cnt = 0; for (Int32 i = 0; i <= 6; i++) { CourseCnt[i] = 0; } Int32 CourseSum = 0; foreach (VcTime time in sch.Matrix.eachTime()) { if (sch.Matrix[time].LsnAct != null && sch.Matrix[time].LsnAct.ClsLesson.Lesson.Course == act.ClsLesson.Lesson.Course) { CourseCnt[(Int32)time.Week]++; CourseSum++; } } foreach (EnLsnAct failAct in sch.FailLsnActs) { if (failAct.ClsLesson.Lesson.Course == act.ClsLesson.Lesson.Course) { CourseSum++; } } if (DaySum == 0) { CourseAverage = 0; } else { CourseAverage = (CourseSum + DaySum - 1) / DaySum; } } //TchConcretes true教师冲突 //ClsLsnRules 规则 //CourseCnt 此课每天已经上的节数(数组) //CourseSum 此课每周总课时 //CourseAverage 每天平均上课节数 DtMatrix <Int32> Advantages = new DtMatrix <Int32>(DataRule.Solution); foreach (VcTime time in sch.Matrix.eachTime()) { if (sch.Matrix[time].LsnAct != null) { Advantages[time] = Int32.MinValue; } else { Advantages[time] = TchConcretes[time] ? -2 : (Int32)ClsLsnRules[time]; if (CourseCnt[(Int32)time.Week] >= CourseAverage) { if (Advantages[time] > -1) { Advantages[time] = -1; //这一天上课比较多 } } } } Int32 MaxAdvantage = Int32.MinValue; VcTime MaxAdvantageTime = new VcTime(); foreach (VcTime time in Advantages.eachTime()) { if (MaxAdvantage < Advantages[time]) { MaxAdvantage = Advantages[time]; time.CopyFieldTo(MaxAdvantageTime); } } if (MaxAdvantage == Int32.MinValue) { return(true); //没地方排了 } if (MaxAdvantage >= -1) { CourseCnt[(Int32)MaxAdvantageTime.Week]++; sch.Matrix[MaxAdvantageTime].LsnAct = act; sch.FailLsnActs.Remove(act); } } foreach (VcTime time in sch.Matrix.eachTime()) { if (sch.FailLsnActs.Count > 0 && sch.Matrix[time].LsnAct == null) { sch.Matrix[time].LsnAct = sch.FailLsnActs[sch.FailLsnActs.Count - 1]; sch.FailLsnActs.RemoveAt(sch.FailLsnActs.Count - 1); } } return(true); }