/// <summary> /// 将所有船舶按划分情况进行合并,坞修替换成划分内组合的坞修大任务,并需求一个坞修资源,然后形成一个新的总项目,进行禁忌搜索 /// </summary> /// <param name="projectPartition"></param> /// <param name="everyCombBestProj"></param> /// <returns></returns> public static RcspspProject calPartitionBestScoreByTabuSearch(List <List <RcspspProject> > projectPartition, Dictionary <String, RcspspProject> everyCombBestProj, bool withMIT = false) { // RcspspProject singleProject = new RcspspProject(); singleProject.BestSocre = int.MaxValue; RcpspJob zeroJob = new RcpspJob(); zeroJob.id = "0"; //zeroJob.isWX = true; zeroJob.isVirtual = true; zeroJob.project = "0"; singleProject.Jobs.AddFirst(zeroJob); //旧Job和复制的新Job的对应表 Dictionary <RcpspJob, RcpspJob> copyMapping = new Dictionary <RcpspJob, RcpspJob>(); RcpspResource resWx = new RcpspResource(); resWx.max_capacity = 1; resWx.renewable = true; singleProject.Resources.AddLast(resWx); //资源添加紧前紧后会更改原有的job,因此需要复制Job,资源和资源使用不会更改resource内容,不用复制,然后除去非坞修任务,添加最前和最后 foreach (List <RcspspProject> projComb in projectPartition) { //先形成字符串() String projCombStr = null; foreach (RcspspProject proj in projComb) { if (projCombStr == null) { projCombStr += proj.ProjectId; } else { projCombStr += "," + proj.ProjectId; } } projCombStr = "(" + projCombStr + ")"; singleProject.BestCombStr += projCombStr; //生成总坞修任务 RcspspProject wxProj = everyCombBestProj[projCombStr]; if (wxProj == null) { throw new Exception("total outer cal " + projCombStr + " cannot find WXCombProject"); } string wxId = null; foreach (RcpspJob job1 in wxProj.Jobs) { if (wxId == null) { wxId = "(" + job1.id + "," + job1.project + ")"; } else { wxId += "→(" + job1.id + "," + job1.project + ")"; } } RcpspJob wxJob = new RcpspJob(); wxJob.id = wxId; wxJob.duration = wxProj.BestSocre; wxJob.addResourceDemand(resWx, 1); wxJob.project = projCombStr; wxJob.isWX = true; singleProject.Jobs.AddLast(wxJob); //再遍历一遍,逐个任务替换并新加到singleProject foreach (RcspspProject proj in projComb) { foreach (RcpspJob job in proj.Jobs) { //if (job.isWX)//坞修任务,不处理 //{ // //如果其紧前为非坞修,要加入到大任务中 //} if (job.isVirtual)//项目的开始和结束虚拟任务都去除,用新的替换 { continue; } RcpspJob newJob = job.isWX?wxJob:job.cloneJob(); //处理紧前关系 foreach (RcpspJob preJob in job.predecessors) { if (preJob.isWX)//坞修的替换成大坞修任务 { //自身就是大坞修任务,不需要处理,自身不是大坞修任务,添加到大坞修任务的紧前关系 if (!newJob.isWX) { newJob.addPredecessor(wxJob); } } else if (preJob.isVirtual) //虚拟的替换成总虚拟节点 { newJob.addPredecessor(zeroJob); } else { //既不是虚拟也不是坞修任务的紧前关系,添加到紧前关系中,此处当前包含坞修 newJob.addPredecessor(copyMapping[preJob]);//正常的查找对应的新任务,添加进入紧前队列 } } copyMapping.Add(job, newJob); if (!newJob.isWX)//坞修大任务已经添加过一遍 { singleProject.Jobs.AddLast(newJob); } } } } //处理整体,对没有紧后任务的添加虚拟结束节点 RcpspJob lastJob = new RcpspJob(); lastJob.id = Convert.ToString(singleProject.Jobs.Count); //lastJob.isWX = true; lastJob.isVirtual = true; lastJob.project = "0"; foreach (RcpspJob job in singleProject.Jobs) { if (job.successors.Count <= 0) { lastJob.addPredecessor(job); } else if (job.predecessors.Count <= 0) { job.addPredecessor(zeroJob); } } singleProject.Jobs.AddLast(lastJob); //计算最优时间 if (withMIT) { singleProject.BestSocre = TabuSearch.getInitScheduleByMIT(singleProject.Jobs, true); } else { singleProject.BestSocre = TabuSearch.solve(singleProject.Jobs, true); } return(singleProject); }
/// <summary> /// 将组合的项目形成一个单项目,并且计算任务的最优排列和最优解,不要使用引用ref或者out,会引起子任务异常 /// </summary> public static RcspspProject calCombBestScoreByTabuSearch(String uniqeId, List <RcspspProject> projComb, bool withMIT = false) { RcspspProject singleProject = new RcspspProject(); singleProject.BestSocre = int.MaxValue; RcpspJob zeroJob = new RcpspJob(); zeroJob.id = "0"; zeroJob.isWX = true; zeroJob.isVirtual = true; zeroJob.project = "0"; singleProject.Jobs.AddFirst(zeroJob); singleProject.BestCombStr += uniqeId; //旧Job和复制的新Job的对应表 Dictionary <RcpspJob, RcpspJob> copyMapping = new Dictionary <RcpspJob, RcpspJob>(); //资源添加紧前紧后会更改原有的job,因此需要复制Job,资源和资源使用不会更改resource内容,不用复制,然后除去非坞修任务,添加最前和最后 foreach (RcspspProject proj in projComb) { foreach (RcpspJob job in proj.Jobs) { if (!job.isWX)//只处理坞修任务 { continue; } RcpspJob newJob = job.cloneJob(); //处理紧前关系 foreach (RcpspJob preJob in job.predecessors) { if (preJob.isWX) { newJob.addPredecessor(copyMapping[preJob]); } else { newJob.addPredecessor(zeroJob); } } copyMapping.Add(job, newJob); singleProject.Jobs.AddLast(newJob); //ngleProject// } } //处理整体,对没有紧后任务的添加虚拟结束节点 RcpspJob lastJob = new RcpspJob(); lastJob.id = Convert.ToString(singleProject.Jobs.Count); lastJob.isWX = true; lastJob.isVirtual = true; lastJob.project = "0"; foreach (RcpspJob job in singleProject.Jobs) { if (job.successors.Count <= 0) { lastJob.addPredecessor(job); } } singleProject.Jobs.AddLast(lastJob); //计算最优时间 if (withMIT) { singleProject.BestSocre = TabuSearch.getInitScheduleByMIT(singleProject.Jobs); } else { singleProject.BestSocre = TabuSearch.solve(singleProject.Jobs); } //Thread.Sleep(5000); //Console.WriteLine("uniqeId=" + uniqeId + " ---------"); return(singleProject); }