예제 #1
0
        public static void print(LinkedList <RcpspJob> globalList, bool withLambda = false)
        {
            double bestCore = TabuSearch.calScheduleCore(globalList, withLambda);
            LinkedListNode <RcpspJob> recursiveNode = globalList.First;

            Console.WriteLine("total cost is " + bestCore);
            Console.WriteLine("jobnr\t\tduaration\t\tstarttime\t\tsucessors");
            while (recursiveNode != null)
            {
                Console.Write(recursiveNode.Value.id + "\t\t\t\t\t" + recursiveNode.Value.startTime + "\t\t" + recursiveNode.Value.duration + "\t\t");
                foreach (RcpspJob suces in recursiveNode.Value.successors)
                {
                    Console.Write(suces.id + "\t");
                }
                Console.WriteLine();
                recursiveNode = recursiveNode.Next;
            }
        }
예제 #2
0
        //禁忌处理,弹出,比较全局最优

        public static double solve(LinkedList <RcpspJob> globalList, bool withLambda = false)
        {
            //生成初始排序和初始解,作为当前最优
            getInitScheduleByMIT(globalList);
            double globalBestScore = calScheduleCore(globalList, withLambda);
            //将当前初始解赋值给全局最优解队列
            LinkedList <RcpspJob>     projJobs     = new LinkedList <RcpspJob>();
            LinkedListNode <RcpspJob> copyRecusive = globalList.First;

            while (copyRecusive != null)
            {
                projJobs.AddLast(copyRecusive.Value);
                copyRecusive = copyRecusive.Next;
            }
            //定义当前领域计算的最优解,初始赋值为全局最优
            double currentBestScore = globalBestScore;
            int    numberIter       = maxIterationNum;
            //长度确定的禁忌表,不足用null对象填充;对禁忌表的操作
            LinkedList <NeighborSwap> tabuList = TabuSearch.initTabuList(TabuSearch.tabuListSize);

            while ((--numberIter) > 0)
            {
#if DEBUG
                Console.Write("执行第 " + (maxIterationNum - numberIter + 1) + "次遍历:");
                print(projJobs);
#endif
                TabuSearch.numberIter++;
                //获取邻居最好的禁忌长度
                LinkedList <NeighborSwap> bestNeighborSwap = getBestNeighborBySwap(projJobs, withLambda);
                //是否优于globalBestScore,是,查询在不在禁忌表中,在的话放到开头,不在加到开头;否,查询非禁忌最优解
                LinkedListNode <NeighborSwap> recursiveNode = bestNeighborSwap.First;

                if (recursiveNode != null && recursiveNode.Value.score < globalBestScore)
                {
#if DEBUG
                    Console.WriteLine("best than global score: swap (" + recursiveNode.Value.from.id + "," + recursiveNode.Value.to.id + ") and core is " + recursiveNode.Value.score);
#endif
                    //置换
                    swapNeighbor(projJobs, projJobs.Find(recursiveNode.Value.from), projJobs.Find(recursiveNode.Value.to));
                    //赋值全局最优和当前最优
                    globalBestScore = currentBestScore = recursiveNode.Value.score;
                    //赋值该列表为全局最优列表
                    copyRecusive = projJobs.First;
                    globalList.Clear();
                    while (copyRecusive != null)
                    {
                        globalList.AddLast(copyRecusive.Value);
                        copyRecusive = copyRecusive.Next;
                    }
                    //更新禁忌表,如果在禁忌表中,将其从列表中移出并加入到最后;如果不存在,直接加到最后
                    LinkedListNode <NeighborSwap> findNode = tabuList.Find(recursiveNode.Value);
                    if (findNode != null)
                    {
                        tabuList.Remove(findNode);
                        tabuList.AddLast(findNode);
                    }
                    else
                    {
                        tabuList.RemoveFirst();
                        tabuList.AddLast(recursiveNode.Value);
                    }
                }
                else
                {
                    //从前到后遍历当前最优解,查找是否在禁忌表中,如果不在,加入到禁忌表最后,并且置换,更新局部最优,但是不更新全局最优;
                    //查到,遍历下一个;当遍历完成都未满足,则最后差一个空的。
                    bool hasLocatedValue = false;
                    while (recursiveNode != null)
                    {
                        if (!tabuList.Contains(recursiveNode.Value))
                        {
#if DEBUG
                            Console.WriteLine("find no in tabulist: swap (" + recursiveNode.Value.from.id + "," + recursiveNode.Value.to.id + ") and core is " + recursiveNode.Value.score);
#endif
                            hasLocatedValue = true;
                            tabuList.RemoveFirst();
                            tabuList.AddLast(recursiveNode.Value);
                            currentBestScore = recursiveNode.Value.score;
                            swapNeighbor(projJobs, projJobs.Find(recursiveNode.Value.from), projJobs.Find(recursiveNode.Value.to));
                            break;//直接返回
                        }
                        recursiveNode = recursiveNode.Next;
                    }
                    if (!hasLocatedValue)
                    {
                        tabuList.RemoveFirst();
                        tabuList.AddLast(new NeighborSwap(null, null, 0));
                    }
                }
#if DEBUG
                Console.Write("current list is :(");
                foreach (RcpspJob job in projJobs)
                {
                    Console.Write(job.id + ",");
                }
                Console.WriteLine(")");
                Console.Write("tabuList is :");
                foreach (NeighborSwap swap in tabuList)
                {
                    if (swap.from != null && swap.to != null)
                    {
                        Console.Write("(" + swap.from.id + "," + swap.to.id + ")");
                    }
                }
                Console.WriteLine();
#endif
            }
            //执行最后,返回全局最优
            return(globalBestScore);
        }
예제 #3
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);
        }
예제 #4
0
        static void Main(string[] args)
        {
            //Dictionary<string, int> did = new Dictionary<string, int>();
            //did.Add("sad", 11);
            //Console.WriteLine("d is " + did["sad"] + " and d1 is " + did["sad1"]);
            //int i = 1023;
            //int j = i / 100;
            //int k = i % 100;
            //Console.WriteLine("d is " + i / 100 + " and d1 is " + k);
            if (args.Length < 1)
            {
                Console.WriteLine(" please input multi-projects file");
                return;
            }
            string fileName = args[0];
            //string fileName = "F:\\VSProject\\TabuSearch\\PSP\\bin\\Release\\000.mp";//args[0];
            RcpspSolver solve = new RcpspSolver();

            solve = RcpspParser.parseMultiProjFile(fileName);
            //solve.TotalWuWeight = 30;
            //solve.ProjectList.AddLast(new RcspspProject("0", 10));
            //solve.ProjectList.AddLast(new RcspspProject("1", 10));
            //solve.ProjectList.AddLast(new RcspspProject("2", 15));
            //solve.ProjectList.AddLast(new RcspspProject("3", 5));
            //solve.ProjectList.AddLast(new RcspspProject("4", 5));
            ////产生所有可行划分和所有划分组合
            solve.generateAllPossiblePartation();
            ////计算所有组合的最优时间和最优分组
            solve.calcAllCombMultiProcess();
            foreach (string str in solve.EveryCombBestProj.Keys)
            {
                RcspspProject proj = solve.EveryCombBestProj[str];
                Console.WriteLine("comb core " + str + "is " + proj.BestSocre + " and list is : ");
                Console.Write("             ");
                foreach (RcpspJob job in proj.Jobs)
                {
                    Console.Write("(" + job.id + "__" + job.project + "__" + job.duration + ")");
                }
                Console.WriteLine();
            }

            RcspspProject bestproj = solve.calAllPartitionScore();

            Console.WriteLine("all project end time is  ");
            foreach (RcspspProject proj in solve.ProjectList)
            {
                if (proj.Jobs.Count > 1)
                {
                    RcpspJob lastJob = proj.Jobs.Last.Previous.Value;
                    Console.Write("   " + (lastJob.startTime + lastJob.duration));
                }
            }
            Console.WriteLine();
            Console.WriteLine("best core is " + bestproj.BestSocre + " and partition is " + bestproj.BestCombStr);
            Console.Write("this List is : ");
            foreach (RcpspJob job in bestproj.Jobs)
            {
                //Console.Write("[" + job.id + "__" + job.project + "__" + job.startTime+"__"+job.duration + "]");
                //foreach(RcspspProject proj in solve.ProjectList){
                //}
                if (job.isWX)
                {
                    RcspspProject wxProject = solve.EveryCombBestProj[job.project];
                    foreach (RcpspJob wxJob in wxProject.Jobs)
                    {
                        addJob2Dic(solve.ProjectList, wxJob, job.startTime);
                    }
                }
                else
                {
                    addJob2Dic(solve.ProjectList, job);
                }
            }
            //TabuSearch.printGUI(bestproj.Jobs);
            Console.WriteLine("total time is " + TabuSearch.calScheduleCore(bestproj.Jobs, true));
            foreach (RcspspProject proj in solve.ProjectList)
            {
                Console.WriteLine("Project " + proj.ProjectId);
                foreach (RcpspJob projJob in proj.Jobs)
                {
                    Console.WriteLine(projJob.id + "\t" + projJob.startTime + "\t" + (projJob.startTime + projJob.duration));
                }
            }

            return;
        }
예제 #5
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);
        }