JSP中求关键路径算法及java实现
2015-05-17 17:03
561 查看
在JSP问题中,关键路径决定着车间作业的完工时间,通过引入基于关键路径的邻域规则,使邻域解大大减少,从而大大减少优化过程的复杂度。
关键块是关键路径中工序在同一台机器连续组成的工序集合。
已知:
算法:
Step 1: 根据最大完工时间,求得最大完工时间所在的工序编号,并将该工序编号加入到关键路径链表中,该工序表示为o
Step 2: 求preJob(o), preMac(o)
Step 3: 若preJob(o) != null && preMac(o) != null,取50%概率选择其一,将新的工序加入插入到关键路径链表,并将该工序表示为o
否则若preJob(o) != null,将preJob(o)插入到关键路径链表,并将该工序表示为o
否则若preMac(o) != null,将preMac(o)插入到关键路径链表,并将该工序表示为o
Step 4: 判断当前关键工序的开始时间是否等于0,如果不是,转Step2, 否则结束
说明:preJob(o):工序o在本工件上的前一工序,且该工序的结束时间等于o的开工时间
preMac(o): 工序o所在机器在o前面紧挨的工序,即该工序的结束时间等于o的开工时间
实现代码:
关键块是关键路径中工序在同一台机器连续组成的工序集合。
已知:
int[][] o = new int [m]; //o代表工序,值为各工序编号,i为工件编号,j为该工件工序编号 int[][] u = new int [m]; //工件i的第j个工序是第几台机器 int[][] p = new int [m]; //工件i的第j个工序的处理时间 int[][] startTime = new int [m]; //startTime[][]存储第i个工件的第j个工序的开始时间 int[][] finishTime = new int [m]; //finished[][]存储第i个工件的第j个工序的完成时间
算法:
Step 1: 根据最大完工时间,求得最大完工时间所在的工序编号,并将该工序编号加入到关键路径链表中,该工序表示为o
Step 2: 求preJob(o), preMac(o)
Step 3: 若preJob(o) != null && preMac(o) != null,取50%概率选择其一,将新的工序加入插入到关键路径链表,并将该工序表示为o
否则若preJob(o) != null,将preJob(o)插入到关键路径链表,并将该工序表示为o
否则若preMac(o) != null,将preMac(o)插入到关键路径链表,并将该工序表示为o
Step 4: 判断当前关键工序的开始时间是否等于0,如果不是,转Step2, 否则结束
说明:preJob(o):工序o在本工件上的前一工序,且该工序的结束时间等于o的开工时间
preMac(o): 工序o所在机器在o前面紧挨的工序,即该工序的结束时间等于o的开工时间
实现代码:
//接下来计算关键路径 //求得最大时间所在的工序编号 int maxIndex = 0; for(int i = 0; i < n; ++i){ if(finishTime[i][9] == maxTime){ maxIndex = i * 10 + 9; } } //将这个工序加入关键路径链表中 ArrayList<Integer> keyPath = new ArrayList<Integer>(); keyPath.add(0, maxIndex); int index_i = maxIndex / n; int index_j = maxIndex % m; //开始递推寻找,直到首工序 while(startTime[index_i][index_j] != 0){ int preJobIndex = -1; int preMacIndex = -1; if(index_j != 0 && finishTime[index_i][index_j - 1] == startTime[index_i][index_j]){//存在前序工序,且结束时间等于当前工序的开始时间 preJobIndex = index_i * 10 + index_j - 1; } for(int i = 0; i < n; ++i){ int mac = u[index_i][index_j]; int macOpe = indi.machines[mac].tasks.get(i); int macOpe_i = macOpe / n; int macOpe_j = macOpe % m; if(finishTime[macOpe_i][macOpe_j] == startTime[index_i][index_j]){ //存在所在机器的前一工序 preMacIndex = macOpe; break; } } if(preJobIndex != -1 && preMacIndex != -1){//同时存在取50%概率选择 if(Math.random() >= 0.5){ keyPath.add(0, preJobIndex); index_j -= 1; } else{ keyPath.add(0, preMacIndex); index_i = preMacIndex / n; index_j = preMacIndex % m; } } else if(preJobIndex != -1){//只存在符合要求的工件前序工序 keyPath.add(0, preJobIndex); index_j -= 1; } else if(preMacIndex != -1){//只存在符合要求的机器前序工序 keyPath.add(0, preMacIndex); index_i = preMacIndex / n; index_j = preMacIndex % m; } }
//接下来对关键路径的工序进行分块 //思路来源于文档倒排索引的Reduce实现 KPB = new ArrayList<KPBlock>(); int preMac = -1; KPBlock kpblock = new KPBlock(); for(int i = 0; i < keyPath.size(); ++i){ int curOpe = keyPath.get(i); int cur_i = curOpe / n; int cur_j = curOpe % m; int curMac = u[cur_i][cur_j]; if(preMac != curMac && preMac != -1){ KPB.add(kpblock); kpblock = new KPBlock(); } preMac = curMac; kpblock.block.add(curOpe); } KPB.add(kpblock); //加上最后一块
class KPBlock{ ArrayList<Integer> block = new ArrayList<Integer>(); }
相关文章推荐
- java实现的项目管理中的关键路径的算法
- 关键路径算法 Java实现
- java实现城市间最短路径算法
- 去哪网笔试 最短路径算法(词梯) Java实现
- 无权最短路径算法java实现
- 迪杰斯特拉(Dijkstra)算法求解单源最短路径及其相应长度(java实现)
- 关键路径过程详解、算法及其实现
- 算法导论——24.2 DAG最短路径算法java实现
- java实现最短路径算法之Dijkstra算法
- 算法实现Java之最短路径迪杰斯特拉(Dijkstra)
- Java实现求最短路径算法——————Dijkstra(迪杰斯特拉)
- Dijkstra最短路径算法浅析及java实现
- 【连载】Dijkstra求最短路径算法设计—Java实现
- Dijkstra最短路径算法的java实现
- 最短路径算法 java实现 - Dijkstra
- 揽货最短路径解决方案算法 - V2(增加了时间维度-客户允许的服务时间段,C#/JAVA同步实现,带python作图)
- 最短路径算法Dijkstra思路及java实现
- Dijkstra算法求单源最短路径Java实现
- 【LeetCode-面试算法经典-Java实现】【063-Unique Paths II(唯一路径问题II)】
- 【LeetCode-面试算法经典-Java实现】【064-Minimum Path Sum(最小路径和)】