Пример #1
0
        /// <summary>
        /// 通过多任务计算所有组合的坞修最优时间好排序
        /// </summary>
        public void calcAllCombMultiProcess()
        {
            //使用task进行多进程异步计算所有的工作
            List <Task <RcspspProject> > tasks = new List <Task <RcspspProject> >();
            int num = everyComb.Keys.Count;

            //每一个combo组合建立一个任务
            foreach (String str in everyComb.Keys)
            {
                if (everyComb[str] == null)
                {
                    return;
                }
                tasks.Add(Task <RcspspProject> .Factory.StartNew(() =>
                {
                    return(calCombBestScoreByTabuSearch(str, everyComb[str]));
                }));
            }
            //等待所有任务结束
            Task.WaitAll(tasks.ToArray());
            //为计算结果进行赋值
            foreach (Task <RcspspProject> task in tasks)
            {
                RcspspProject project = task.Result;
                everyCombBestProj[project.BestCombStr] = project;
            }
        }
Пример #2
0
        /// <summary>
        /// 将每一个划分中的项目非坞修和坞修大任务形成一个单项目,计算任务的最优解。然后提取所有组合中的最优解
        /// </summary>
        public RcspspProject calAllPartitionScore()
        {
            int num = allPartition.Count;
            List <Task <RcspspProject> > tasks = new List <Task <RcspspProject> >();

            //每一个combo组合建立一个任务
            foreach (List <List <RcspspProject> > projectPartition in this.allPartition)
            {
                tasks.Add(Task <RcspspProject> .Factory.StartNew(() =>
                {
                    return(calPartitionBestScoreByTabuSearch(projectPartition, this.everyCombBestProj));
                }));
            }
            //等待所有任务结束
            Task.WaitAll(tasks.ToArray());

            //为计算结果进行赋值
            double        allPartitionBestScore = double.MaxValue;
            RcspspProject bestPartitionProj     = null;

            foreach (Task <RcspspProject> task in tasks)
            {
                RcspspProject project = task.Result;
//#if DEBUG
                Console.WriteLine("best core is " + project.BestSocre + " and partition is " + project.BestCombStr);
                Console.Write("this List is : ");
                foreach (RcpspJob job in project.Jobs)
                {
                    Console.Write("[" + job.id + "__" + job.project + "__" + job.duration + "]");
                }
                Console.WriteLine();
//#endif
                if (allPartitionBestScore > project.BestSocre)
                {
                    allPartitionBestScore = project.BestSocre;
                    bestPartitionProj     = project;
                }
            }
            return(bestPartitionProj);
        }
Пример #3
0
        public static RcpspSolver parseMultiProjFile(string fileName)
        {
            RcpspSolver solver = new RcpspSolver();

            if (!fileName.EndsWith(".mp"))
            {
                solver.IsMultiProject = false;
            }
            solver.IsMultiProject = true;
            string       directoryPath = fileName.Substring(0, fileName.LastIndexOf("\\"));
            StreamReader fileSR        = new StreamReader(fileName);
            string       readLineStr   = null;
            int          lineNumber    = 0;
            int          projNum       = 0;
            int          projIndex     = 0;
            int          resNum        = 0;
            int          perProjLine   = 1;
            Regex        numRegex      = new Regex(@"[-+]?\d*(\.(?=\d))?\d+");

            while ((readLineStr = fileSR.ReadLine()) != null)
            {
                if (lineNumber == 0)
                {
                    //第0行总吨位
                    solver.TotalWuWeight = Convert.ToInt32(numRegex.Match(readLineStr).Value);
                }
                else if (lineNumber == 1)
                {
                    //资源数量
                    resNum = Convert.ToInt32(numRegex.Match(readLineStr).Value);
                }
                else if (lineNumber == 2)
                {
                    //资源详情
                    MatchCollection match1 = numRegex.Matches(readLineStr);
                    foreach (Match g in match1)
                    {
                        RcpspResource res = new RcpspResource();
                        res.renewable    = true;
                        res.max_capacity = Convert.ToInt32(g.Value);
                        solver.ResourceList.AddLast(res);
                        resNum--;
                        if (resNum <= 0)
                        {
                            break;
                        }
                    }
                }
                else if (lineNumber == 3)
                {
                    //第1行项目数量
                    projNum = Convert.ToInt32(numRegex.Match(readLineStr).Value);
                }
                else if (lineNumber > 3 || lineNumber < (3 + projNum * perProjLine))//
                {
                    //依次为文件,每个文件每个文件解析
                    string        smFileName = readLineStr.Trim(new char[] { ' ', '\t', '\r' });
                    RcspspProject proj       = generateFromSMFile(directoryPath + "\\" + smFileName, solver);
                    proj.ProjectId = Convert.ToString(projIndex + 1);
                    solver.ProjectList.AddLast(proj);
                    projIndex++;
                }

                lineNumber++;
            }
            return(solver);
        }
Пример #4
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);
        }
Пример #5
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;
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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);
        }
Пример #8
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);
        }
Пример #9
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);
        }