コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <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);
        }