private static void MergeToNodelist(List<Project> nodeList, List<Project> mergeList, DateTime startScheduleTime, Position schPostion) { foreach (var project in mergeList) { if (project.Status != stat.待办) continue; bool insert = false; for (int index = 0; index < nodeList.Count - 1; index++) { if (index == 0 && nodeList[0].StartTime - Max(startScheduleTime, project.StartLine) > project.AssumeTime && (project.position == null || project.position == GetPos(nodeList, index, schPostion))) { project.SetStartTime(Max(startScheduleTime, project.StartLine)); nodeList.Insert(0, project); insert = true; break; } if (nodeList[index + 1].StartTime - Max(nodeList[index].FinishedTime.Value, project.StartLine) > project.AssumeTime && (project.position == null || project.position == GetPos(nodeList, index, schPostion))) { project.SetStartTime(Max(nodeList[index].FinishedTime, project.StartLine)); nodeList.Insert(index + 1, project); insert = true; break; } } if (!insert)//非插入,从最后加入 { project.SetStartTime(nodeList.Count > 0 ? Max(nodeList[nodeList.Count - 1].FinishedTime.Value, project.StartLine) : Max(startScheduleTime, project.StartLine)); nodeList.Add(project); } } }
static Position GetPos(List<Project> list, int afterThis, Position startPos) { int count = 0; Position pos = startPos; foreach (var p in list) { count++; if (p.toPosition != null) pos = p.toPosition; if (count >= afterThis) break; } return pos; }
public static void Init() { planManager.Init(); IO.Init(); ProjectList = ReadToDoProject(DateTime.Today.AddDays(1));//加载数据 ProjectList.AddRange(ReadProject(DateTime.Today, DateTime.Today.AddDays(1))); ProjectList = ProjectList.Distinct().ToList(); RoutineToProject(DateTime.Now, ProjectList); planManager.PlansGetSubProject(plansProjectList, AllProjectList()); positionNow = CaculatePosNow(); Schedule(); RoutineList.ForEach(r => r.CaculateAccumulate()); RoutineList.Sort(); RoutineList.Reverse(); }
//无解、最优:尽量少空闲,同时可以的时候,sl比没有sl的优先 public static List<Project> Schedule(List<Project> projectList, Position schPostion = null, bool seek = false) { if (schPostion == null) { schPostion = CaculatePosNow(); if (seek == false) { positionNow = schPostion; Form1.Instance.CorrectPosition(); } } TimeSpan intervalTime = new TimeSpan(0, 0, 0);//项目与项目间隔时间 List<Project> nodeList = new List<Project>(); RemoveRelax(projectList); Project doingProject = projectList.Find(p => p.Status == stat.正在进行); DateTime startScheduleTime = doingProject?.FinishedTime ?? DateTime.Now; //12个以上的已完成的任务,移出列表 //后天以上的任务移出列表 projectList.Sort(); for (int index = projectList.Count - 1, overItem = 0; index >= 0; index--) { var timeSpan = projectList[index].StartLine - startScheduleTime; if (timeSpan != null && ((TimeSpan)timeSpan).Days > 2) { exceptTodayProjectList.Add(projectList[index]); exceptTodayProjectList = exceptTodayProjectList.Distinct().ToList(); projectList[index].SetStartTime(projectList[index].StartLine); projectList.Remove(projectList[index]); continue; } if (projectList[index].Status == stat.完成) { overItem++; if (overItem > 10) { exceptTodayProjectList.Add(projectList[index]); exceptTodayProjectList = exceptTodayProjectList.Distinct().ToList(); projectList.Remove(projectList[index]); } } } //得到能改变position的project的list //List<Project> positionList = RemovePositionTransProject(projectList); //nodeList.AddRange(positionList); //将有时间要求的节点移到nodeList,ProjectList里只保留剩下的项目,包括放弃、完成项目以及没有时间限制的待办项目 for (int index = 0; index < projectList.Count; index++) { switch (projectList[index].Status) { case stat.待办: case stat.时间已过: projectList[index].Status = stat.待办; if (projectList[index].DeadLine != null || projectList[index].StartLine != null) { nodeList.Add(projectList[index]); projectList.Remove(projectList[index]); index--; } break; } } //处理时间已过的DL project ,将只有startline的project扔掉 List<Project> onlyStartList = new List<Project>(); foreach (Project project in nodeList) { if (project.DeadLine != null && project.DeadLine < startScheduleTime + project.AssumeTime) { project.SetStartTime(project.DeadLine - project.AssumeTime); project.Status = stat.时间已过; projectList.Add(project); } else if (project.DeadLine == null && project.StartLine != null) { onlyStartList.Add(project); } } nodeList = nodeList.Except(projectList).ToList(); nodeList = nodeList.Except(onlyStartList).ToList(); //按dl排序 nodeList.Sort((n1, n2) => n1.DeadLine < n2.DeadLine ? -1 : 1); //将project 按顺序从now开始排列,同时将不能有解的丢掉 DateTime startTime = startScheduleTime; nodeList.ForEach(n => { n.SetStartTime(startTime); if (n.DeadLine != null && n.FinishedTime > n.DeadLine) { n.Status = stat.时间已过; projectList.Add(n); } else { startTime = (DateTime)n.FinishedTime; } }); nodeList = nodeList.Except(projectList).ToList(); //处理只有dl和dl、sl都有的project startTime = startScheduleTime; for (int handle = 0; handle < nodeList.Count; handle++) { Project project = nodeList[handle]; project.SetStartTime(startTime); //有sl要求的project if (project.StartLine != null && startTime < project.StartLine) { for (int index = handle + 1; index < nodeList.Count; index++) { var temp = nodeList[index]; //TODO:modify if (temp.StartLine == null) { if (startTime + temp.AssumeTime + project.AssumeTime < project.DeadLine.Value) { temp.SetStartTime(startTime); startTime = temp.FinishedTime.Value; nodeList.Remove(temp); nodeList.Insert(handle, temp); handle++; } } else if (temp.StartLine < project.StartLine) { if (startTime + temp.AssumeTime + project.AssumeTime < project.DeadLine.Value) { temp.SetStartTime(Max(startTime, temp.StartLine)); startTime = temp.FinishedTime.Value; nodeList.Remove(temp); nodeList.Insert(handle, temp); handle++; } } if (project.StartLine < startTime) { break; } } } if (startTime + project.AssumeTime > project.DeadLine.Value) { project.Status = stat.时间已过; } else { project.SetStartTime(project.StartLine == null ? startTime : Max(startTime, project.StartLine)); startTime = project.FinishedTime.Value; } } //仅有sl的project插入 onlyStartList.Sort((p1, p2) => { if (p1.toPosition != null && p2.toPosition == null) return -1; if (p1.toPosition == null && p2.toPosition != null) return 1; return p1.StartLine < p2.StartLine ? -1 : 1; });//有地点转换的优先,其次是sl早的 //TODO:有地点需求的优先? MergeToNodelist(nodeList, onlyStartList, startScheduleTime, schPostion); //普通项目的插空和添加; MergeToNodelist(nodeList, projectList, startScheduleTime, schPostion); projectList = projectList.Union(nodeList).ToList(); AddRelax(projectList, startScheduleTime); RefreshRemindTime(); return projectList; }
private void btnCreatePosition_Click(object sender, EventArgs e) { Position pos = new Position(txtPosition.Text); pos.ID = ++Position.IDmax; Logic.PositonList.Add(pos); this.cbPosition.Items.Add(pos.name); this.cbTransmitPostion.Items.Add(pos.name); }