コード例 #1
0
        public bool removeJob(RcpspJob job)
        {
            LinkedListNode <RcpspJob> jobNode = _jobs.Find(job);

            if (jobNode == null)
            {
                return(true);
            }
            job.removeAllProdecessors();
            job.removeAllSuccessors();
            _jobs.Remove(jobNode);
            return(true);
        }
コード例 #2
0
        public RcpspJob cloneJob()
        {
            RcpspJob cloneJob = new RcpspJob();

            cloneJob.duration        = this.duration;
            cloneJob.project         = this.project;
            cloneJob.isWX            = this.isWX;
            cloneJob.resourcesDemand = this.resourcesDemand;
            cloneJob.id         = this.id;
            cloneJob.sourceProj = this.sourceProj;
            cloneJob.isFirst    = this.isFirst;
            cloneJob.isLast     = this.isLast;
            //cloneJob.recipt = this.recipt;
            return(cloneJob);
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: DianmingHou/TabuSearch
 public static void addJob2Dic(LinkedList <RcspspProject> projs, RcpspJob job, double additionTime = 0)
 {
     if (job.project == "0")
     {
         return;
     }
     //查找到所在的project
     foreach (RcspspProject proj in projs)
     {
         if (job.project.Equals(proj.ProjectId))
         {
             foreach (RcpspJob projJob in proj.Jobs)
             {
                 if (job.id == projJob.id)
                 {
                     projJob.startTime = additionTime + job.startTime;
                     break;
                 }
             }
             break;
         }
     }
 }
コード例 #4
0
ファイル: TabuSearch.cs プロジェクト: DianmingHou/TabuSearch
        /// <summary>
        /// 计算当前任务排列的总得分(最大完工时间),并且会计算任务列表中每一个任务的开始时间
        /// </summary>
        /// <param name="projJobs"></param>
        /// <returns></returns>
        public static double calScheduleCore(LinkedList <RcpspJob> projJobs, bool withLambda)
        {
            //当前调度最大完工时间
            double totalLamda = 0.0;//未兼容最早节点或者最终节点为坞修任务的情况
            Dictionary <RcspspProject, double> projsFirstJob = new Dictionary <RcspspProject, double>();
            double totalMaxTime = -1;
            //时间安排逐个进行遍历
            LinkedListNode <RcpspJob> curNode = projJobs.First;

            while (curNode != null)
            {
                RcpspJob curJob = curNode.Value;
                //通过获取当前任务的所有紧前任务的结束时间,取其中最大,确定一个紧前最早开工时间
                HashSet <RcpspJob> preds = curJob.predecessors;
                double             predEarliestStartTime = 0;
                foreach (RcpspJob job in preds)
                {
                    double endTime = job.startTime + job.duration;
                    if (predEarliestStartTime < endTime)
                    {
                        predEarliestStartTime = endTime;
                    }
                }
                //获取其需要的所有资源
                IDictionary <RcpspResource, int> resourceDemands = curJob.resourcesDemand;
                //计算资源占用时,以当前任务资源满足并且在持续时间duration内都满足,视为该任务可以安排在此时间
                int    loadTime             = 0;
                double resEarliestStartTime = predEarliestStartTime;
                while (loadTime <= curJob.duration)
                {
                    //当前时间点
                    double currentTime = resEarliestStartTime + loadTime;
                    bool   isUpLimit   = false;
                    //查找该时间点在执行的任务对该任务资源消耗的需求
                    foreach (RcpspResource resource in resourceDemands.Keys)
                    {
                        //if (resourceDemands[resource] <= 0)continue;//资源需求为0的情况,此种在处理时就剔除了
                        int resourceUsed = resourceDemands[resource];
                        //从后往前遍历整个list,查看时间交集的任务
                        LinkedListNode <RcpspJob> recursiveNode = curNode.Previous;
                        while (recursiveNode != null)
                        {
                            if (!recursiveNode.Value.resourcesDemand.ContainsKey(resource))
                            {//资源无交集,继续往前遍历
                            }
                            else if (currentTime >= recursiveNode.Value.startTime && currentTime < recursiveNode.Value.startTime + recursiveNode.Value.duration)
                            {//判断该任务时候有交集,大于等于开始时间,小于开始时间+持续时间
                                //累加资源消耗
                                resourceUsed += recursiveNode.Value.resourcesDemand[resource];
                                if (resourceUsed > resource.max_capacity)
                                {
                                    //当此时已经超了,直接跳出
                                    isUpLimit = true;
                                    break;
                                }
                            }
                            else
                            {
                                //资源有交集但是时间不交叉
                            }
                            //继续往前遍历
                            recursiveNode = recursiveNode.Previous;
                        }
                        //只要有一个资源超上限,都直接退出
                        if (isUpLimit)
                        {
                            break;
                        }
                    }
                    if (isUpLimit)
                    {//资源超总数,时间后移,并且累积时间归零
                        resEarliestStartTime++;
                        loadTime = 0;
                    }
                    else
                    { //资源总数不超,时间暂时不变,累积时间递增
                        loadTime++;
                    }
                }
                //设置当前项目的最早开始时间
                curJob.startTime = resEarliestStartTime;
                if (withLambda && curJob.sourceProj != null)
                {
                    if (projsFirstJob.Keys.Contains(curJob.sourceProj))
                    {
                        projsFirstJob[curJob.sourceProj] = curJob.startTime < projsFirstJob[curJob.sourceProj]?curJob.startTime:projsFirstJob[curJob.sourceProj];
                    }
                    else
                    {
                        projsFirstJob[curJob.sourceProj] = curJob.startTime;
                    }
                }
                if (withLambda && curJob.isLast && curJob.sourceProj != null)//最后一个任务一定在最早一个任务的额后边出现
                {
                    totalLamda += curJob.sourceProj.Lambda * (curJob.startTime + curJob.duration - projsFirstJob[curJob.sourceProj]);
                }
                //保存一个全任务最大完工时间,也可以通过遍历任务队列的开始时间获得
                if (totalMaxTime < resEarliestStartTime + curJob.duration)
                {
                    totalMaxTime = resEarliestStartTime + curJob.duration;
                }

                //当前处理结束,进行下一个循环,计算队列下一个节点
                curNode = curNode.Next;
            }
            if (withLambda)
            {
                return(totalLamda);
            }
            return(totalMaxTime);
        }
コード例 #5
0
ファイル: TabuSearch.cs プロジェクト: DianmingHou/TabuSearch
        /// <summary>
        /// 检查当前任务的紧前任务是否在队列指定位置之前
        /// </summary>
        /// <param name="projJobs"></param>
        /// <param name="index"></param>
        /// <param name="curJob"></param>
        /// <returns></returns>
        public static bool feasibleByPred(LinkedList <RcpspJob> projJobs, LinkedListNode <RcpspJob> lastNode, RcpspJob curJob)
        {
            HashSet <RcpspJob> preds = curJob.predecessors;
            bool allFinded           = true;

            foreach (RcpspJob job in preds)
            {
                bool finded = false;
                LinkedListNode <RcpspJob> recursiveNode = lastNode;
                while (recursiveNode != null)
                {
                    if (recursiveNode.Value == job)
                    {
                        finded = true;
                    }
                    recursiveNode = recursiveNode.Previous;
                }
                if (!finded)
                {
                    allFinded = false;
                    break;
                }
            }
            return(allFinded);
        }
コード例 #6
0
ファイル: TabuSearch.cs プロジェクト: DianmingHou/TabuSearch
 public NeighborSwap(RcpspJob from, RcpspJob to, double score)
 {
     this.from  = from;
     this.to    = to;
     this.score = score;
 }
コード例 #7
0
        /// <summary>
        /// 从从*.sm文件构造Project,添加一个已经构造的solver构造多项目
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="solver"></param>
        /// <returns></returns>
        public static RcspspProject generateFromSMFile(string fileName, RcpspSolver solver)
        {
            RcspspProject proj = new RcspspProject();
            LinkedList <RcpspResource> resourceList = solver.IsMultiProject ? solver.ResourceList : proj.Resources;

            proj.Resources = solver.ResourceList;
            LinkedList <RcpspJob> jobList = proj.Jobs;
            StreamReader          fileSR  = new StreamReader(fileName);
            string     readLineStr        = null;
            LoadStatus loadState          = LoadStatus.HEADER_SECTION;
            long       lineNumber         = 0;
            //获取数字的正则表达式,包[-]2[.32]
            Regex numRegex = new Regex(@"[-+]?\d*(\.(?=\d))?\d+");

            while ((readLineStr = fileSR.ReadLine()) != null)
            {
                lineNumber++;
                readLineStr = readLineStr.TrimStart(new char[] { ' ', '\t', '\r' });
                if (readLineStr.StartsWith("**") || readLineStr.StartsWith("--"))
                {
                    continue;
                }
                switch (loadState)
                {
                case LoadStatus.HEADER_SECTION: {
                    if (readLineStr.StartsWith("file"))
                    {
                        proj.BaseFile = readLineStr.Substring(readLineStr.IndexOf(":")).Trim();        //项目baseFile
                    }
                    else if (readLineStr.StartsWith("init"))
                    {
                        string numberStr = numRegex.Match(readLineStr).Value;
                        proj.RandomSeed = Convert.ToInt32(numberStr);        //
                    }
                    else if (readLineStr.StartsWith("projects") || readLineStr.StartsWith("jobs"))
                    {
                        loadState = LoadStatus.PROJECT_SECTION;
                        goto case LoadStatus.PROJECT_SECTION;
                    }
                    else
                    {
                        throw new Exception("File Format error at line " + lineNumber + "!");
                    }
                } break;

                case LoadStatus.PROJECT_SECTION: {
                    if (readLineStr.StartsWith("projects"))
                    {
                        string numberStr = numRegex.Match(readLineStr).Value;        //项目编号
                        proj.ProjectId = numberStr;
                    }
                    else if (readLineStr.StartsWith("jobs"))
                    {
                        int    indexOfM  = readLineStr.IndexOf(":");
                        string numberStr = numRegex.Match(readLineStr.Substring(indexOfM)).Value;
                        //获取项目内任务数量
                        proj.TaskNumber = Convert.ToInt32(numberStr);
                        int index = 0;
                        while (index < proj.TaskNumber)
                        {
                            RcpspJob job = new RcpspJob();
                            job.project    = proj.ProjectId;
                            job.id         = Convert.ToString(index + 1);
                            job.sourceProj = proj;

                            if (index == 0 || index == proj.TaskNumber - 1)
                            {
                                job.isVirtual = true;
                            }
                            if (index == 1)
                            {
                                job.isFirst = true;
                            }
                            if (index == proj.TaskNumber - 2)
                            {
                                job.isLast = true;
                            }
                            jobList.AddLast(job);
                            index++;
                        }
                    }
                    else if (readLineStr.StartsWith("horizon"))
                    {
                        string numberStr = numRegex.Match(readLineStr).Value;
                        proj.Horizon = Convert.ToInt32(numberStr);
                    }
                    else if (readLineStr.StartsWith("RESOURCES"))
                    {
                    }
                    else if (readLineStr.StartsWith("weight"))
                    {
                        proj.Weight = Convert.ToInt32(numRegex.Match(readLineStr).Value);
                    }
                    else if (readLineStr.StartsWith("lambda"))
                    {
                        proj.Lambda = Convert.ToDouble(numRegex.Match(readLineStr).Value);
                    }
                    else if (readLineStr.Contains("- renewable"))
                    {
                        string numberStr = numRegex.Match(readLineStr).Value;
                        proj.RenewableResourceNumber = Convert.ToInt32(numberStr);
                        int index = proj.RenewableResourceNumber;
                        if (!solver.IsMultiProject)
                        {
                            //不处理
                            while (index > 0)
                            {
                                RcpspResource res = new RcpspResource();
                                res.renewable = true;
                                solver.ResourceList.AddLast(res);
                                index--;
                            }
                        }
                    }
                    else if (readLineStr.Contains("- nonrenewable"))
                    {
                        string numberStr = numRegex.Match(readLineStr).Value;
                        proj.NonrenewableResourceNumber = Convert.ToInt32(numberStr);
                        //int index = this._nonrenewableResourceNumber;
                        //while (index < 0)
                        //{
                        //    RcpspResource res = new RcpspResource();
                        //    res.renewable = false;
                        //    solver.ResourceList.AddLast(res);
                        //    index--;
                        //}
                    }
                    else if (readLineStr.Contains("- doubly constrained"))
                    {
                        string numberStr = numRegex.Match(readLineStr).Value;
                        proj.DoubleConstResourceNumber = Convert.ToInt32(numberStr);
                    }
                    else if (readLineStr.StartsWith("PROJECT INFORMATION"))
                    {
                        loadState = LoadStatus.PROJECT_INFO_SECTION;
                        goto case LoadStatus.PROJECT_INFO_SECTION;
                    }
                    else if (readLineStr.StartsWith("PRECEDENCE"))
                    {
                        loadState = LoadStatus.PRECEDENCE_SECTION;
                        goto case LoadStatus.PRECEDENCE_SECTION;
                    }
                    else if (readLineStr.StartsWith("REQUESTS/DURATIONS"))
                    {
                        loadState = LoadStatus.REQUEST_SECTION;
                        goto case LoadStatus.REQUEST_SECTION;
                    }
                    else if (readLineStr.StartsWith("RESOURCEAVAILABILITIES"))
                    {
                        loadState = LoadStatus.RESOURCE_SECTION;
                        goto case LoadStatus.RESOURCE_SECTION;
                    }
                    else
                    {
                        throw new Exception("File Format error at line " + lineNumber + "!");
                    }
                } break;

                case LoadStatus.PROJECT_INFO_SECTION: {
                    if (readLineStr.StartsWith("pronr."))
                    {
                    }
                    else if (readLineStr.StartsWith("PRECEDENCE"))
                    {
                        loadState = LoadStatus.PRECEDENCE_SECTION;
                        goto case LoadStatus.PRECEDENCE_SECTION;
                    }
                    else if (readLineStr.StartsWith("REQUESTS/DURATIONS"))
                    {
                        loadState = LoadStatus.REQUEST_SECTION;
                        goto case LoadStatus.REQUEST_SECTION;
                    }
                    else if (readLineStr.StartsWith("RESOURCEAVAILABILITIES"))
                    {
                        loadState = LoadStatus.RESOURCE_SECTION;
                        goto case LoadStatus.RESOURCE_SECTION;
                    }
                    else if (readLineStr.StartsWith("PROJECT INFORMATION"))
                    {
                    }
                    else
                    {
                        //MatchCollection matchColl = numRegex.Matches(readLineStr);
                        //int index = 0;
                        //foreach (Match g in matchColl)
                        //{
                        //    index++;
                        //    if (index == 0)
                        //    {
                        //        //项目号
                        //    }
                        //    else if (index == 1)
                        //    {
                        //        //任务数
                        //    }
                        //    else if (index == 2)
                        //    {
                        //        //rel.date
                        //    }
                        //    else if (index == 3)
                        //    {
                        //        //duedate
                        //    }
                        //    else if (index == 4)
                        //    {
                        //        //tardcost
                        //    }
                        //    else if (index == 5) {
                        //        //MPM-Time
                        //    }
                        //}
                    }
                }
                break;

                case LoadStatus.PRECEDENCE_SECTION: {
                    if (readLineStr.StartsWith("REQUESTS/DURATIONS"))
                    {
                        loadState = LoadStatus.REQUEST_SECTION;
                        goto case LoadStatus.REQUEST_SECTION;
                    }
                    else if (readLineStr.StartsWith("RESOURCEAVAILABILITIES"))
                    {
                        loadState = LoadStatus.RESOURCE_SECTION;
                        goto case LoadStatus.RESOURCE_SECTION;
                    }
                    else if (readLineStr.StartsWith("jobnr."))
                    {
                        //
                    }
                    else if (readLineStr.StartsWith("PRECEDENCE"))
                    {
                        //
                    }
                    else
                    {
                        MatchCollection matchColl = numRegex.Matches(readLineStr);
                        int             index     = 0;
                        int             numProd   = 0;
                        RcpspJob        job       = null;
                        foreach (Match g in matchColl)
                        {
                            int num = Convert.ToInt32(g.Value);;
                            if (index == 0)
                            {
                                //任务数
                                job = jobList.ElementAt(num - 1);
                                if (job == null)
                                {
                                    throw new Exception("REQUESTS/DURATIONS not exist job nr. " + num);
                                }
                                index++;
                            }
                            else if (index == 1)
                            {
                                //mode
                                if (job != null)
                                {
                                    job.isWX = num == 1 ? true : false;
                                }
                                index++;
                            }
                            else if (index == 2)
                            {
                                //紧前任务数量
                                index++;
                                numProd = num;
                                if (num == 0)
                                {
                                    break;
                                }
                            }
                            else if (index == 3)
                            {
                                RcpspJob predJob = jobList.ElementAt(num - 1);
                                if (predJob == null)
                                {
                                    throw new Exception("Predecessor No. is error" + num);
                                }
                                job.addPredecessor(predJob);
                                numProd--;
                                if (numProd <= 0)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                //if(numProd>0)throw new Exception("Predecessors num is not correct!");
                            }
                        }
                    }
                } break;

                case LoadStatus.REQUEST_SECTION: {
                    if (readLineStr.StartsWith("jobnr.") || readLineStr.StartsWith("REQUESTS/DURATIONS"))
                    {
                    }
                    else if (readLineStr.StartsWith("RESOURCEAVAILABILITIES"))
                    {
                        loadState = LoadStatus.RESOURCE_SECTION;
                        goto case LoadStatus.RESOURCE_SECTION;
                    }
                    else if (readLineStr.StartsWith("PRECEDENCE"))
                    {
                    }
                    else
                    {
                        MatchCollection matchColl = numRegex.Matches(readLineStr);
                        int             index     = 0;
                        RcpspJob        job       = null;
                        foreach (Match g in matchColl)
                        {
                            if (index == 0)
                            {
                                int num = Convert.ToInt32(g.Value);
                                //任务数
                                job = jobList.ElementAt(num - 1);
                                if (job == null)
                                {
                                    throw new Exception("REQUESTS/DURATIONS not exist job nr. " + num);
                                }
                                index++;
                            }
                            else if (index == 1)
                            {
                                int num = Convert.ToInt32(g.Value);
                                //不处理
                                index++;
                            }
                            else if (index == 2)
                            {
                                //duration
                                double num = Convert.ToDouble(g.Value);
                                index++;
                                if (job != null)
                                {
                                    job.duration = num;
                                }
                            }
                            else
                            {
                                //不判断资源超界了
                                int num = Convert.ToInt32(g.Value);
                                if (num > 0)
                                {
                                    RcpspResource res = resourceList.ElementAt(index - 3);
                                    if (res != null)
                                    {
                                        job.addResourceDemand(res, num);
                                    }
                                }
                                index++;
                            }
                        }
                    }
                } break;

                case LoadStatus.RESOURCE_SECTION: {
                    if (readLineStr.StartsWith("PRECEDENCE"))
                    {
                        loadState = LoadStatus.PRECEDENCE_SECTION;
                        goto case LoadStatus.PRECEDENCE_SECTION;
                    }
                    else if (readLineStr.StartsWith("REQUESTS/DURATIONS"))
                    {
                        loadState = LoadStatus.REQUEST_SECTION;
                        goto case LoadStatus.REQUEST_SECTION;
                    }
                    else if (readLineStr.StartsWith("RESOURCEAVAILABILITIES"))
                    {
                        //
                    }
                    else
                    {
                        MatchCollection matchColl = numRegex.Matches(readLineStr);
                        if (!solver.IsMultiProject)
                        {
                            //
                            int index = 0;
                            foreach (Match g in matchColl)
                            {
                                index++;
                                if (index == 0)
                                {
                                    //任务数
                                }
                            }
                        }
                    }
                } break;

                case LoadStatus.RESOURCE_MIN_SECTION: {
                } break;

                case LoadStatus.PARSING_FINISHED: break;

                case LoadStatus.ERROR_FOUND: break;

                default: break;
                }
            }
            //solver.ProjectList.AddLast(proj);
            return(proj);
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: DianmingHou/TabuSearch
        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;
        }
コード例 #9
0
ファイル: Program.cs プロジェクト: DianmingHou/TabuSearch
        public static void generateProj(RcspspProject spspProject)
        {
            int[] resCap = { 3, 4, 2, 3, 6 };
            for (int i = 0; i < 5; i++)
            {
                RcpspResource resource = new RcpspResource();
                resource.max_capacity = resCap[i];
                spspProject.Resources.AddLast(resource);
            }
            int numberJobs = 22;

            int[] durations = { 0, 10, 8, 20, 4, 8, 4, 10, 6, 12, 5, 22, 13, 4, 10, 8, 2, 16, 25, 8, 2, 0 };
            int[,] resUsed =
            {
                { 0, 0, 0, 0, 0 },         //0
                { 2, 0, 2, 1, 0 },         //1
                { 0, 1, 0, 2, 5 },         //2
                { 1, 0, 2, 0, 0 },         //3
                { 0, 0, 0, 3, 5 },         //4
                { 0, 2, 0, 0, 2 },         //5
                { 0, 2, 1, 0, 0 },         //6
                { 2, 0, 2, 0, 0 },         //7
                { 1, 0, 0, 2, 5 },         //8
                { 0, 1, 0, 0, 2 },         //9
                { 0, 0, 0, 3, 0 },         //10
                { 1, 0, 0, 0, 0 },         //11
                { 2, 2, 0, 0, 0 },         //12
                { 0, 0, 2, 3, 0 },         //13
                { 0, 0, 0, 1, 4 },         //14
                { 1, 0, 0, 1, 3 },         //15
                { 0, 0, 0, 1, 2 },         //16
                { 2, 3, 0, 0, 0 },         //17
                { 1, 0, 2, 0, 0 },         //18
                { 0, 2, 0, 3, 0 },         //19
                { 0, 3, 0, 0, 6 },         //20
                { 0, 0, 0, 0, 0 } //21
            };
            int [][] pp = new int[22][];
            pp[0] = new int[] { 0 };              //1
            pp[1] = new int[] { 0 };              //2
            pp[2] = new int[] { 1 };              //3
            pp[3] = new int[] { 0 };              //4
            pp[4] = new int[] { 3 };              //5
            pp[5] = new int[] { 2, 4 };           //6

            pp[6]  = new int[] { 0 };             //7
            pp[7]  = new int[] { 6 };             //8
            pp[8]  = new int[] { 7 };             //9
            pp[9]  = new int[] { 7 };             //10
            pp[10] = new int[] { 8, 9 };          //11

            pp[11] = new int[] { 0 };             //12
            pp[12] = new int[] { 11 };            //13
            pp[13] = new int[] { 11 };            //14
            pp[14] = new int[] { 12, 13 };        //15
            pp[15] = new int[] { 14 };            //16

            pp[16] = new int[] { 0 };             //17
            pp[17] = new int[] { 16 };            //18
            pp[18] = new int[] { 0 };             //19
            pp[19] = new int[] { 17, 18 };        //20
            pp[20] = new int[] { 19 };            //21
            pp[21] = new int[] { 5, 10, 15, 20 }; //22

            for (int j = 0; j < numberJobs; j++)
            {
                RcpspJob job = new RcpspJob();
                job.id       = Convert.ToString(j);
                job.duration = durations[j];
                for (int resN = 0; resN < 5; resN++)
                {
                    if (resUsed[j, resN] > 0)
                    {
                        job.addResourceDemand(spspProject.Resources.ElementAt(resN), resUsed[j, resN]);
                    }
                }
                for (int preIndex = 0; preIndex < pp[j].Length; preIndex++)
                {
                    if (pp[j][preIndex] != j)
                    {
                        job.addPredecessor(spspProject.Jobs.ElementAt(pp[j][preIndex]));
                    }
                }
                spspProject.Jobs.AddLast(job);
            }
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: DianmingHou/TabuSearch
 public Edge(RcpspJob from, RcpspJob to)
 {
     this.from = from;
     this.to   = to;
 }
コード例 #11
0
ファイル: Program.cs プロジェクト: DianmingHou/TabuSearch
 public Edge()
 {
     from = to = null;
 }
コード例 #12
0
ファイル: Program.cs プロジェクト: DianmingHou/TabuSearch
        public static void generateRandomProj(RcspspProject spspProject)
        {
            Random rd = new Random();

            for (int i = 0; i < 5; i++)
            {
                RcpspResource resource = new RcpspResource();
                resource.max_capacity = rd.Next(1, 10);
                spspProject.Resources.AddLast(resource);
            }
            RcpspJob zeroJob = new RcpspJob();

            zeroJob.duration = 0;
            zeroJob.id       = "0";
            spspProject.Jobs.AddLast(zeroJob);
            //初始Job,每一个job都有不允许建立的关系,即前置已经建立的关系,存放起来Dictionary<Job,Job>存在
            LinkedList <Edge> existEdges = new LinkedList <Edge>();
            int numberJobs  = 5;
            int durationMax = 11;

            for (int j = 1; j < numberJobs + 1; j++)
            {
                RcpspJob job = new RcpspJob();
                job.id = Convert.ToString(j);
                //检查可以生成的边的数量
                int edgeCount = 0;
                LinkedListNode <RcpspJob> node = spspProject.Jobs.First;
                while (node != null)
                {
                    //检测是否不允许
                    bool isAllow = true;
                    //遍历列表
                    foreach (Edge ed in existEdges)
                    {
                        if (ed.from == job && ed.to == node.Value)
                        {
                            isAllow = false;
                            break;
                        }
                    }
                    if (!isAllow)
                    {
                        continue;
                    }
                    //是否生成
                    if (rd.Next(0, 2) > 0)
                    {
                        edgeCount++;
                        job.addPredecessor(node.Value);
                        Edge edThis = new Edge();
                        edThis.from = job;
                        edThis.to   = node.Value;
                        existEdges.AddLast(edThis);
                        //将前置的所有不允许加入当前的
                        LinkedListNode <Edge> lastNode = existEdges.Last;
                        while (lastNode != null)
                        {
                            Edge ed = lastNode.Value;
                            if (ed.from == node.Value)
                            {
                                Edge edNew = new Edge();
                                edNew.from = job;
                                edNew.to   = ed.to;
                                existEdges.AddLast(edNew);
                            }
                            lastNode = lastNode.Previous;
                        }
                    }
                    node = node.Next;
                }
                if (edgeCount == 0)
                {
                    job.addPredecessor(spspProject.Jobs.First.Value);
                    existEdges.AddLast(new Edge(job, spspProject.Jobs.First.Value));
                }
                if (j == numberJobs - 1)
                {
                    job.duration = 0;
                }
                else
                {
                    job.duration = rd.Next(1, durationMax);
                    //随机资源使用
                    for (int i = 0; i < 5; i++)
                    {
                        RcpspResource resource       = spspProject.Resources.ElementAt(i);
                        int           resourceDemand = rd.Next(0, resource.max_capacity + 1);
                        if (resourceDemand > 0)
                        {
                            job.addResourceDemand(resource, resourceDemand);
                        }
                    }
                }


                spspProject.Jobs.AddLast(job);
            }
            //添加最后工序
            RcpspJob lastJob = new RcpspJob();

            lastJob.duration = 0;
            lastJob.id       = Convert.ToString(numberJobs + 1);
            //所有没有紧后任务的工序都设一条到该点的边
            for (LinkedListNode <RcpspJob> recuNode = spspProject.Jobs.First; recuNode != null; recuNode = recuNode.Next)
            {
                if (recuNode.Value.successors.Count <= 0)
                {
                    lastJob.addPredecessor(recuNode.Value);
                }
            }
            spspProject.Jobs.AddLast(lastJob);
        }
コード例 #13
0
 public void addPredecessor(RcpspJob pred)
 {
     pred.successors.Add(this);
     this.predecessors.Add(pred);
 }
コード例 #14
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);
        }
コード例 #15
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);
        }