- 浏览: 76068 次
- 性别:
- 来自: 北京
最新评论
-
贝塔ZQ:
实现导出word模板文件,可以用插件试试么,那么多插件的,Pa ...
利用Itext画模板导出word,纯java实现 -
tangqingzhu:
请问Lz能定点插入图片或者表格、文字么??能不能给个QQ 。
利用Itext画模板导出word,纯java实现 -
allmajor:
学习一下
利用Itext画模板导出word,纯java实现 -
zl-2577:
痛苦不忧伤 写道if(document.form1){docu ...
10秒后自动跳转网页 -
痛苦不忧伤:
if(document.form1){document.for ...
10秒后自动跳转网页
基本概念:
在关键路径法中,一般有以下一些时间参数:
最早开始时间(Early Start)活动最早开始时间由所有前置活动中最后一个最早结束时间确定。
最早结束时间(Early Finish)活动的最早结束时间由活动的最早开始时间加上其工期确定。
最迟结束时间(Late Finish)一个活动在不耽误整个项目的结束时间的情况下能够最迟开始的时间。它等于所有紧后工作中最早的一个最晚开始时间。
最迟开始时间(Late Start)一个活动在不耽误整个项目的结束时间的情况下能够最早开始的时间。它等于活动的最迟结束时间减去活动的工期。
总时差(Total Float) 指一项活动在不影响整体计划工期的情况下最大的浮动时间。
自由时差(Free Float)指活动在不影响其紧后工作的最早开始时间的情况下可以浮动的时间。
*
*
算法原理-前导图(PDM)法:
对于活动的最早开始和最早结束时间,采用正推法计算,其算法如下所示:
1.将第一个活动的最早开始时间设置为1.
2.在活动的最早开始时间上加上其工期,得到活动的最早结束时间。
3.根据该活动与后置活动的逻辑关系,计算后置活动应该的最早开始时间,并与其已有的最早开始时间对比,如果其后置活动还没有设置最早开始时间,则将此时间设为其最早开始时间,如果此时间早于其后置活动已有的最早开始时间,则保留后置活动的原有最早开始时间,如果此时间迟于其后置活动已有的最早开始时间,则将此时间设置为后置活动的最迟开始时间。
4.重复步骤2和3,直到所有活动的时间被计算完为止。
对于以上所示的最早时间的计算过程,可以以公式的形式表示如下:
当活动间的逻辑关系为SS,则计算如下
ESj=max{ ESi + STS}
当活动间的逻辑关系为FS,则计算如下
ESj= max{ESi+ Di+ FTS}
当活动间的逻辑关系为FF,计算如下
ESj= max{ESi+ Di - Dj +FTF}
当活动间的逻辑关系为SF,计算如下
ESj=max{ ESi - Dj +STF}
在计算出各个活动的最早开始和结束时间之后,就可以计算活动的自由时差,在计算前导图(PDM)的自由时差时应注意,由于引入了多种逻辑关系,并且活动间可以存在延时,所以其计算方法与箭线图(ADM)的计算方法不一样。
对于前导图(PDM)的活动间,除了延时还可以存在时间间隔(LAG),一般可以按照下面的方式计算。
当活动间的逻辑关系为SS,则计算如下
LAGi-j= ESj- ESi- STS
当活动间的逻辑关系为FS,则计算如下
LAGi-j= ESj- EFi- FTS
当活动间的逻辑关系为FF,计算如下
LAGi-j= EFj- EFi- FTF
当活动间的逻辑关系为SF,计算如下
LAGi-j= EFj- ESi- STF
则对于任意一个活动,其自由时差为
FFi=min{ LAGi-j}
最后一个活动的自由时差为0.
对于总时差,终点节点的总时差为0,对于其它任意一个节点,总时差按照下式进行计算
TFi=min{TFj+ LAGi-j}
对于任意一个活动的最晚开始时间可以由其最早开始时间加上总时差得到,同样,其最晚开始时间可以由最早结束时间加上其总时差得到,公式表示如下
LSi=ESi+TFi
LFi=EFi+TFi
还有一个封装测试类,利用随机数模拟蒙特卡洛模拟法(
http://baike.baidu.com/view/2692033.htm
)
在关键路径法中,一般有以下一些时间参数:
最早开始时间(Early Start)活动最早开始时间由所有前置活动中最后一个最早结束时间确定。
最早结束时间(Early Finish)活动的最早结束时间由活动的最早开始时间加上其工期确定。
最迟结束时间(Late Finish)一个活动在不耽误整个项目的结束时间的情况下能够最迟开始的时间。它等于所有紧后工作中最早的一个最晚开始时间。
最迟开始时间(Late Start)一个活动在不耽误整个项目的结束时间的情况下能够最早开始的时间。它等于活动的最迟结束时间减去活动的工期。
总时差(Total Float) 指一项活动在不影响整体计划工期的情况下最大的浮动时间。
自由时差(Free Float)指活动在不影响其紧后工作的最早开始时间的情况下可以浮动的时间。
*
*
算法原理-前导图(PDM)法:
对于活动的最早开始和最早结束时间,采用正推法计算,其算法如下所示:
1.将第一个活动的最早开始时间设置为1.
2.在活动的最早开始时间上加上其工期,得到活动的最早结束时间。
3.根据该活动与后置活动的逻辑关系,计算后置活动应该的最早开始时间,并与其已有的最早开始时间对比,如果其后置活动还没有设置最早开始时间,则将此时间设为其最早开始时间,如果此时间早于其后置活动已有的最早开始时间,则保留后置活动的原有最早开始时间,如果此时间迟于其后置活动已有的最早开始时间,则将此时间设置为后置活动的最迟开始时间。
4.重复步骤2和3,直到所有活动的时间被计算完为止。
对于以上所示的最早时间的计算过程,可以以公式的形式表示如下:
当活动间的逻辑关系为SS,则计算如下
ESj=max{ ESi + STS}
当活动间的逻辑关系为FS,则计算如下
ESj= max{ESi+ Di+ FTS}
当活动间的逻辑关系为FF,计算如下
ESj= max{ESi+ Di - Dj +FTF}
当活动间的逻辑关系为SF,计算如下
ESj=max{ ESi - Dj +STF}
在计算出各个活动的最早开始和结束时间之后,就可以计算活动的自由时差,在计算前导图(PDM)的自由时差时应注意,由于引入了多种逻辑关系,并且活动间可以存在延时,所以其计算方法与箭线图(ADM)的计算方法不一样。
对于前导图(PDM)的活动间,除了延时还可以存在时间间隔(LAG),一般可以按照下面的方式计算。
当活动间的逻辑关系为SS,则计算如下
LAGi-j= ESj- ESi- STS
当活动间的逻辑关系为FS,则计算如下
LAGi-j= ESj- EFi- FTS
当活动间的逻辑关系为FF,计算如下
LAGi-j= EFj- EFi- FTF
当活动间的逻辑关系为SF,计算如下
LAGi-j= EFj- ESi- STF
则对于任意一个活动,其自由时差为
FFi=min{ LAGi-j}
最后一个活动的自由时差为0.
对于总时差,终点节点的总时差为0,对于其它任意一个节点,总时差按照下式进行计算
TFi=min{TFj+ LAGi-j}
对于任意一个活动的最晚开始时间可以由其最早开始时间加上总时差得到,同样,其最晚开始时间可以由最早结束时间加上其总时差得到,公式表示如下
LSi=ESi+TFi
LFi=EFi+TFi
package com.ryan.activity; import java.util.LinkedList; import java.util.List; /** * TASK基础类 * * @author ryan */ public class Task { private String taskNumber;//任务编号 private String logic;//任务之间的逻辑关系 private double earlyStartTime;//最早开始时间 private double earlyFinishTime;//最早结束时间 private double lateStartTime;//最晚开始时间 private double lateFinishTime;//最晚结束时间 private double dut;//执行时间 private double delayTime;//延迟时间 private double slack;//机动时间 private String[] logicArray;//任务之间的逻辑关系 private double[] earlyStartTimeArray;//最早开始时间 private double[] earlyFinishTimeArray;//最早结束时间 private double[] lateStartTimeArray;//最晚开始时间 private double[] lateFinishTimeArray;//最晚结束时间 private double[] dutArray;//执行时间 private double[] delayTimeArray;//延迟时间 private double[] slackArray;//机动时间 private boolean isCalEST = false;//是否计算了最早开始时间 private boolean isCalEFT = false;//是否计算了最早结束时间 private boolean isCalLST = false;//是否计算了最晚开始时间 private boolean isCalLFT = false;//是否计算了最晚结束时间 private boolean isCalSlack = false;//是否计算了机动时间 private boolean isCalETArray = false;//是否计算了最早开始时间 private boolean isCalLTArray = false;//是否计算了最晚开始时间 private boolean isCalSlackArray = false;//是否计算了机动时间 private boolean isCriticalPath = false;//是否是关键路径 private List<Task> previousTasks = new LinkedList<Task>();//前置任务集合 private List<Task> nextTasks = new LinkedList<Task>();//后置任务集合 /* * 计算最早开始时间 */ public void calculateET(){ if(!this.isCalEST()){ double est = 0.0d;//临时存放最早开始时间 boolean isTmp = false;//标记是否执行了逻辑关系中的代码 if(this.getPreviousTasks().size()==0){//第一个任务是没有前置任务的,所以其最早开始时间是0 this.earlyStartTime = est; this.isCalEST = true; } else { if("FS".equals(logic)){//ES= max{ES(前)+ Dur(前)+ FTS} for(Task previousTask : this.getPreviousTasks()){ if(previousTask.getEarlyFinishTime()>est && previousTask.isCalEFT()){ est = previousTask.getEarlyFinishTime(); isTmp = previousTask.isCalEFT(); } } est = est + this.getDelayTime(); }else if("FF".equals(logic)){//ES= max{ES(前)+ Dur(前) - Dur +FTF} for(Task previousTask : this.getPreviousTasks()){ if(previousTask.getEarlyFinishTime()>est && previousTask.isCalEFT()){ est = previousTask.getEarlyFinishTime(); isTmp = previousTask.isCalEFT(); } } est = est + this.getDelayTime() - this.getDut(); }else if("SS".equals(logic)){//ES=max{ ES(前) + STS} for(Task previousTask : this.getPreviousTasks()){ if(previousTask.getEarlyStartTime()>est && previousTask.isCalEST()){ est = previousTask.getEarlyStartTime(); isTmp = previousTask.isCalEST(); } } est = est + this.getDelayTime(); }else if("SF".equals(logic)){//ES=max{ ES(前) - Dur +STF} for(Task previousTask : this.getPreviousTasks()){ if(previousTask.getEarlyStartTime()>est && previousTask.isCalEST()){ est = previousTask.getEarlyStartTime(); isTmp = previousTask.isCalEST(); } } est = est - this.getDut() + this.getDelayTime(); } if(isTmp){ this.earlyStartTime = est; this.isCalEST = true; } } } if(!this.isCalEFT() && this.isCalEST()){ this.earlyFinishTime = this.getEarlyStartTime() + this.getDut(); this.isCalEFT = true; } } /* *计算最晚时间 */ public void calculateLT(){ if(!this.isCalLST()){ calculateLT(this.nextTasks,this); } if(!this.isCalLFT()){ calculateLT(this.nextTasks,this); } } /* * task的后置任务nextTasks */ public void calculateLT(List<Task> nextTasks,Task task){ double tmpSlack = 0.0d;//临时时间差 boolean isTmp = false;//标记 if(nextTasks.size()==0 ){ if(task.isCalEST() && task.isCalEFT()){ task.lateFinishTime = task.getEarlyFinishTime(); task.slack = 0.0d; task.isCalLFT = true; task.isCalSlack = true; task.lateStartTime = task.getEarlyStartTime(); task.slack = 0.0d; task.isCalLST = true; task.isCalSlack = true; } } else{ for(int i = 0; i<nextTasks.size(); i++){ Task nextTask = nextTasks.get(i); if(!nextTask.isCalLFT()) return; if(!nextTask.isCalLST()) return; if(nextTask.isCalSlack){ double _tmp = tmpSlack;//临时时间间隔 if("FS".equals(nextTask.logic) && nextTask.isCalEST() && task.isCalEFT()){//Slack = min{slack后+ES后-EF-FTS} _tmp = nextTask.getSlack() + nextTask.getEarlyStartTime() - task.getEarlyFinishTime() - nextTask.getDelayTime(); isTmp = true; }else if("FF".equals(nextTask.logic) && nextTask.isCalEFT() && task.isCalEFT()){//Slack = min{slack后+EF后-EF-FTF} _tmp = nextTask.getSlack() + nextTask.getEarlyFinishTime() - task.getEarlyFinishTime() - nextTask.getDelayTime(); isTmp = true; }else if("SF".equals(nextTask.logic) && nextTask.isCalEFT() && task.isCalEST()){//Slack = min{slack后+EF后-ES-STF} _tmp = nextTask.getSlack() + nextTask.getEarlyFinishTime() - task.getEarlyStartTime() - nextTask.getDelayTime(); isTmp = true; }else if("SS".equals(nextTask.logic) && nextTask.isCalEST() && task.isCalEST()){//Slack = min{slack后+ES后-ES-STS} _tmp = nextTask.getSlack() + nextTask.getEarlyStartTime() - task.getEarlyStartTime() - nextTask.getDelayTime(); isTmp = true; } if(i==0){ tmpSlack = _tmp; } if(_tmp < tmpSlack ){ tmpSlack = _tmp; } } } } if(isTmp && task.isCalEST() && task.isCalEFT()){//isTmp标记为true,说明已经经过计算。 task.lateFinishTime = task.getEarlyFinishTime() + tmpSlack; task.setSlack(tmpSlack); task.isCalLFT = true; task.isCalSlack = true; task.lateStartTime = task.getEarlyStartTime() + tmpSlack; task.setSlack(tmpSlack); task.isCalLST = true; task.isCalSlack = true; } } /* * 计算最早开始和最早结束时间 * */ public void calculateETArray(){ if(!this.isCalETArray()){ double[] dutArray = this.getDutArray(); double[] delayTimeArray = this.getDelayTimeArray(); String[] logicArray = this.getLogicArray(); double[] earlyStartTimeArray = new double[dutArray.length]; double[] earlyFinishTimeArray = new double[dutArray.length]; int ETCount = 0; for (int i=0;i<dutArray.length;i++) { this.setDelayTime(delayTimeArray[i]); this.setLogic(logicArray[i]); this.setDut(dutArray[i]); this.calculateET(); earlyStartTimeArray[i] = this.getEarlyStartTime(); earlyFinishTimeArray[i] = this.getEarlyFinishTime(); ETCount++; } if(ETCount==dutArray.length){ this.setEarlyStartTimeArray(earlyStartTimeArray); this.setEarlyFinishTimeArray(earlyFinishTimeArray); this.setCalETArray(true); } } } /* * 计算最晚开始和最晚结束时间 * */ public void calculateLTArray(){ if(!this.isCalLTArray()){ double[] dutArray = this.getDutArray(); double[] delayTimeArray = this.getDelayTimeArray(); String[] logicArray = this.getLogicArray(); double[] lateStartTimeArray = new double[dutArray.length]; double[] lateFinishTimeArray = new double[dutArray.length]; int LTCount = 0; for (int i=0;i<dutArray.length;i++) { this.setDelayTime(delayTimeArray[i]); this.setLogic(logicArray[i]); this.setDut(dutArray[i]); this.calculateLT(); lateStartTimeArray[i] = this.getLateStartTime(); lateFinishTimeArray[i] = this.getLateFinishTime(); LTCount++; } if(LTCount==dutArray.length){ this.setLateStartTimeArray(lateStartTimeArray); this.setLateFinishTimeArray(lateFinishTimeArray); this.setCalLTArray(true); } } } /* * taskNumber 任务编号 * logic 与前置任务的逻辑关系 * dut 任务执行时间 *delayTime 提前滞后时间 */ public Task(String taskNumber,String logic, double dut, double delayTime) { super(); this.taskNumber = taskNumber; this.logic = logic; this.dut = dut; this.delayTime = delayTime; } /* * taskNumber 任务编号 * logic 与前置任务的逻辑关系 * dut 任务执行时间数组 * delayTime 提前滞后时间数组 */ public Task(String taskNumber,String[] logicArray, double[] dutArray, double[] delayTimeArray) { super(); this.taskNumber = taskNumber; this.logicArray = logicArray; this.dutArray = dutArray; this.delayTimeArray = delayTimeArray; } public String getTaskNumber() { return taskNumber; } public void setTaskNumber(String taskNumber) { this.taskNumber = taskNumber; } public double getDelayTime() { return delayTime; } public void setDelayTime(double delayTime) { this.delayTime = delayTime; } public double getDut() { return dut; } public void setDut(double dut) { this.dut = dut; } public double getEarlyFinishTime() { return earlyFinishTime; } public double getEarlyStartTime() { return earlyStartTime; } public double getLateFinishTime() { return lateFinishTime; } public double getLateStartTime() { return lateStartTime; } public double getSlack(){ return slack; } public void setSlack(double slack){ this.slack = slack; } public boolean isCalEST(){; return isCalEST; } public boolean isCalEFT(){; return isCalEFT; } public boolean isCalLST(){ return isCalLST; } public boolean isCalLFT(){ return isCalLFT; } public boolean isCriticalPath(){ return isCriticalPath; } public List<Task> getPreviousTasks() { return previousTasks; } public String getLogic() { return logic; } public void setLogic(String logic) { this.logic = logic; } public void setPreviousTasks(List<Task> previousTasks) { this.previousTasks = previousTasks; for (Task task : this.previousTasks) { task.getNextTasks().add(this); } } public List<Task> getNextTasks() { return nextTasks; } public void setNextTasks(List<Task> nextTasks) { this.nextTasks = nextTasks; } public String[] getLogicArray() { return logicArray; } public void setLogicArray(String[] logicArray) { this.logicArray = logicArray; } public double[] getDelayTimeArray() { return delayTimeArray; } public void setDelayTimeArray(double[] delayTimeArray) { this.delayTimeArray = delayTimeArray; } public double[] getDutArray() { return dutArray; } public void setDutArray(double[] dutArray) { this.dutArray = dutArray; } public double[] getEarlyFinishTimeArray() { return earlyFinishTimeArray; } public void setEarlyFinishTimeArray(double[] earlyFinishTimeArray) { this.earlyFinishTimeArray = earlyFinishTimeArray; } public double[] getEarlyStartTimeArray() { return earlyStartTimeArray; } public void setEarlyStartTimeArray(double[] earlyStartTimeArray) { this.earlyStartTimeArray = earlyStartTimeArray; } public double[] getLateFinishTimeArray() { return lateFinishTimeArray; } public void setLateFinishTimeArray(double[] lateFinishTimeArray) { this.lateFinishTimeArray = lateFinishTimeArray; } public double[] getLateStartTimeArray() { return lateStartTimeArray; } public void setLateStartTimeArray(double[] lateStartTimeArray) { this.lateStartTimeArray = lateStartTimeArray; } public double[] getSlackArray() { return slackArray; } public void setSlackArray(double[] slackArray) { this.slackArray = slackArray; } public boolean isCalSlackArray() { return isCalSlackArray; } public void setCalSlackArray(boolean isCalSlackArray) { this.isCalSlackArray = isCalSlackArray; } public boolean isCalETArray() { return isCalETArray; } public void setCalETArray(boolean isCalETArray) { this.isCalETArray = isCalETArray; } public boolean isCalLTArray() { return isCalLTArray; } public void setCalLTArray(boolean isCalLTArray) { this.isCalLTArray = isCalLTArray; } public void setCriticalPath() { if(this.isCalLST() && this.isCalEST()){ if(this.getLateStartTime()-this.getEarlyStartTime()==0) this.isCriticalPath = true; } } public void setCriticalPathArray() { if(this.isCalLTArray() && this.isCalETArray()){ //TODO 待完成 } } }
还有一个封装测试类,利用随机数模拟蒙特卡洛模拟法(
http://baike.baidu.com/view/2692033.htm
)
package com.ryan.activity; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.Set; /** * Task的计算逻辑类 * * @author ryan */ public class Wbs { private List<Task> tasks;//所有任务集合 private Set<Task> noPreviousTasks;//没有前置任务的任务集合 private Set<Task> noNextTasks;//没有后置任务的任务集合 /** * @param tasks 所有任务集合 * @return 没有前置任务的任务集合 */ public Set<Task> getNoPreviousTasks(List<Task> tasks){ if(tasks!=null && tasks.size()>0){ for(Task task : tasks){ if(task!=null && task.getPreviousTasks().size()==0){ this.noPreviousTasks.add(task); } } } return this.noPreviousTasks; } /** * @param tasks 所有任务集合 * @return 没有后置任务的任务集合 */ public Set<Task> getNoNextTasks(List<Task> tasks){ if(tasks!=null && tasks.size()>0){ for(Task task : tasks){ if(task!=null && task.getNextTasks().size()==0){ this.noNextTasks.add(task); } } } return this.noNextTasks; } /** * @param tasks 所有任务 * @return 没有前置任务计算完成之后,待计算的任务 */ private Set<Task> calculateNoPreviousEarlyTime(List<Task> tasks){ // System.out.println("开始调用calculateNoPreviousEarlyTime(List<Task> tasks)------"); Set<Task> calTasks = new LinkedHashSet<Task>(); if(tasks!=null && tasks.size()>0){ Set<Task> noPreviousTasks = this.getNoPreviousTasks(tasks); for(Task task : noPreviousTasks){ // System.out.println("没有前置任务的是"+task.getTaskNumber()); if(!task.isCalEST()&&!task.isCalEFT()) task.calculateET(); calTasks.add(task); } } // System.out.println("结束调用calculateNoPreviousEarlyTime(List<Task> tasks)------"); return calTasks; } /** * @param nextTasks 本次待计算的任务 * @return 下一次待计算的任务 */ public Set<Task> calculateEarlyTime(Set<Task> nextTasks){ Set<Task> calTasks = new LinkedHashSet<Task>(); if(nextTasks!=null && nextTasks.size()>0){ Iterator<Task> it = nextTasks.iterator(); while(it.hasNext()){ Task task = it.next(); // System.out.println("本次需要计算的任务是"+task.getTaskNumber()); //找到本任务的前置任务看是不是全部计算完成了, List<Task> befTask = task.getPreviousTasks(); //判断本任务的前置任务是不是完全计算完成的计数器 int count = 0;//计数器 for(int i=0;i<befTask.size();i++){ Task bfTask = befTask.get(i); if(bfTask.isCalEST() && bfTask.isCalEFT()) count++; } //如果全部计算完成,将本任务的后置任务加入到返回列表里 if(count==befTask.size()){ task.calculateET(); // System.out.println("已经计算了"+task.getTaskNumber()); calTasks.addAll(task.getNextTasks()); //如果没有全部计算完成,把本任务加入到计算列表里 }else{ calTasks.add(task); } } } return calTasks; } /** * @param tasks 所有任务 * @return 没有前置任务的下一层需要计算的任务 */ public Set<Task> calNoNextTasksLateTime(List<Task> tasks){ Set<Task> calTasks = new LinkedHashSet<Task>(); if(tasks!=null && tasks.size()>0){ for (Task task : this.getNoNextTasks(tasks)) { if(!task.isCalLST()&&!task.isCalLFT()) task.calculateLT(); calTasks.add(task); } } return calTasks; } /** * @param nextTasks 本次待计算的任务 * @return 下一次需要计算的任务 */ public Set<Task> calculateLateTime(Set<Task> nextTasks){ Set<Task> calTasks = new LinkedHashSet<Task>(); if(nextTasks!=null && nextTasks.size()>0){ Iterator<Task> it = nextTasks.iterator(); while(it.hasNext()){ Task task = it.next(); //找到本任务的后置任务看是不是全部计算完成了, List<Task> nextTask = task.getNextTasks(); //判断本任务的后置任务是不是完全计算完成的计数器 int count = 0;//计数器 for(int i=0;i<nextTask.size();i++){ Task ntTask = nextTask.get(i); if(ntTask.isCalLST()&&ntTask.isCalLFT()) count++; } //如果全部计算完成,将本任务的后置任务加入到返回列表里 if(count==nextTask.size()){ task.calculateLT(); // System.out.println("计算的是"+task.getTaskNumber()); calTasks.addAll(task.getPreviousTasks()); //如果没有全部计算完成,把本任务加入到计算列表里 }else{ calTasks.add(task); } } } return calTasks; } /* * 计算最早最晚时间 */ public void calculateTime() { //计算没有前置任务的任务 Set<Task> firstTimes = calculateNoPreviousEarlyTime(this.tasks); //依次分层计算后一层的任务EST,EFT Set<Task> nextTimes = calculateEarlyTime(firstTimes); Set<Task> tmpTasks; do{ tmpTasks = nextTimes; nextTimes = calculateEarlyTime(tmpTasks); }while(nextTimes.size()>0); firstTimes.clear(); nextTimes.clear(); tmpTasks.clear(); //计算没有后置任务的任务 firstTimes = calNoNextTasksLateTime(this.tasks); //依次分层计算后一层的任务的LST nextTimes = calculateLateTime(firstTimes); do{ tmpTasks = nextTimes; nextTimes = calculateLateTime(tmpTasks); }while(nextTimes.size()>0); //打印计算结果 for (Task task : this.tasks) { System.out.println(task.getTaskNumber()+"tnumber=="+task.getEarlyStartTime()+"est==="+task.getEarlyFinishTime()+"eft==="+task.getLateStartTime()+"lst==="+task.getLateFinishTime()+"lft===="+task.isCriticalPath()); } } /** * @param tasks 所有任务 * @return 没有前置任务计算完成之后,待计算的任务 */ private Set<Task> calculateNoPreviousEarlyTimeArray(List<Task> tasks){ // System.out.println("开始调用calculateNoPreviousEarlyTime(List<Task> tasks)------"); Set<Task> calTasks = new LinkedHashSet<Task>(); if(tasks!=null && tasks.size()>0){ Set<Task> noPreviousTasks = this.getNoPreviousTasks(tasks); for(Task task : noPreviousTasks){ // System.out.println("没有前置任务的是"+task.getTaskNumber()); if(!task.isCalETArray()){ task.calculateETArray(); System.out.println("计算了第一个"+task.getTaskNumber()+"tnumber=="+task.getEarlyStartTime()+"est==="+task.getEarlyFinishTime()+"eft==="); calTasks.add(task); } } } // System.out.println("结束调用calculateNoPreviousEarlyTime(List<Task> tasks)------"); return calTasks; } /** * @param nextTasks 本次待计算的任务 * @return 下一次待计算的任务 */ public Set<Task> calculateEarlyTimeArray(Set<Task> nextTasks){ Set<Task> calTasks = new LinkedHashSet<Task>(); if(nextTasks!=null && nextTasks.size()>0){ Iterator<Task> it = nextTasks.iterator(); while(it.hasNext()){ Task task = it.next(); // System.out.println("本次需要计算的任务是"+task.getTaskNumber()); //找到本任务的前置任务看是不是全部计算完成了, List<Task> befTask = task.getPreviousTasks(); //判断本任务的前置任务是不是完全计算完成的计数器 int count = 0;//计数器 for(int i=0;i<befTask.size();i++){ Task bfTask = befTask.get(i); if(bfTask.isCalETArray()) count++; } //如果全部计算完成,将本任务的后置任务加入到返回列表里 if(count==befTask.size()){ task.calculateETArray(); // System.out.println("已经计算了"+task.getTaskNumber()); calTasks.addAll(task.getNextTasks()); //如果没有全部计算完成,把本任务加入到计算列表里 }else{ calTasks.add(task); } } } return calTasks; } /** * @param tasks 所有任务 * @return 没有前置任务的下一层需要计算的任务 */ public Set<Task> calNoNextTasksLateTimeArray(List<Task> tasks){ Set<Task> calTasks = new LinkedHashSet<Task>(); if(tasks!=null && tasks.size()>0){ for (Task task : this.getNoNextTasks(tasks)) { if(!task.isCalLTArray()) task.calculateLTArray(); calTasks.add(task); } } return calTasks; } /** * @param nextTasks 本次待计算的任务 * @return 下一次需要计算的任务 */ public Set<Task> calculateLateTimeArray(Set<Task> nextTasks){ Set<Task> calTasks = new LinkedHashSet<Task>(); if(nextTasks!=null && nextTasks.size()>0){ Iterator<Task> it = nextTasks.iterator(); while(it.hasNext()){ Task task = it.next(); //找到本任务的后置任务看是不是全部计算完成了, List<Task> nextTask = task.getNextTasks(); //判断本任务的后置任务是不是完全计算完成的计数器 int count = 0;//计数器 for(int i=0;i<nextTask.size();i++){ Task ntTask = nextTask.get(i); if(ntTask.isCalLTArray()) count++; } //如果全部计算完成,将本任务的后置任务加入到返回列表里 if(count==nextTask.size()){ task.calculateLTArray(); // System.out.println("计算的是"+task.getTaskNumber()); calTasks.addAll(task.getPreviousTasks()); //如果没有全部计算完成,把本任务加入到计算列表里 }else{ calTasks.add(task); } } } return calTasks; } /* * 计算最早最晚时间 */ public void calculateTimeArray() { //计算没有前置任务的任务 Set<Task> firstTimes = calculateNoPreviousEarlyTimeArray(this.tasks); //依次分层计算后一层的任务EST,EFT Set<Task> nextTimes = calculateEarlyTimeArray(firstTimes); Set<Task> tmpTasks; do{ tmpTasks = nextTimes; nextTimes = calculateEarlyTimeArray(tmpTasks); }while(nextTimes.size()>0); firstTimes.clear(); nextTimes.clear(); tmpTasks.clear(); //计算没有后置任务的任务 firstTimes = calNoNextTasksLateTimeArray(this.tasks); //依次分层计算后一层的任务的LST nextTimes = calculateLateTimeArray(firstTimes); do{ tmpTasks = nextTimes; nextTimes = calculateLateTimeArray(tmpTasks); }while(nextTimes.size()>0); //打印计算结果 for (int i =0; i<this.tasks.size();i++) { Task task = this.tasks.get(i); System.out.println(task.getTaskNumber()+"tnumber=="+task.getEarlyStartTimeArray()[0]+"est==="+task.getEarlyFinishTimeArray()[0]+"eft==="+task.getLateStartTimeArray()[0]+"lst==="+task.getLateFinishTimeArray()[0]+"lft"); } } public List<Task> getTasks() { return tasks; } public void setTasks(List<Task> tasks) { this.tasks = tasks; } public Set<Task> getNoNextTasks() { return getNoNextTasks(tasks); } public Set<Task> getNoPreviousTasks() { return getNoPreviousTasks(tasks); } /* * tasks 所有任务集合 */ public Wbs(List<Task> tasks) { super(); this.tasks = tasks; this.noNextTasks = new LinkedHashSet<Task>(); this.noPreviousTasks = new LinkedHashSet<Task>(); } public static void main(String args[]){ // String[] l1 = {"FS"}; // double[] d1 = {15}; // double[] dl1 = {0}; // Task t1 = new Task("1",l1,d1,dl1); // String[] l2 = {"FS"}; // double[] d2 = {20}; // double[] dl2 = {-5}; // Task t2 = new Task("2",l2,d2,dl2); // String[] l3 = {"FS"}; // double[] d3 = {26}; // double[] dl3 = {0}; // Task t3 = new Task("3",l3,d3,dl3); // String[] l4 = {"SS"}; // double[] d4 = {18}; // double[] dl4 = {10}; // Task t4 = new Task("4",l4,d4,dl4); // String[] l5 = {"FS"}; // double[] d5 = {15}; // double[] dl5 = {0}; // Task t5 = new Task("5",l5,d5,dl5); // String[] l6 = {"FS"}; // double[] d6 = {38}; // double[] dl6 = {0}; // Task t6 = new Task("6",l6,d6,dl6); // String[] l7 = {"FS"}; // double[] d7 = {25}; // double[] dl7 = {-5}; // Task t7 = new Task("7",l7,d7,dl7); // String[] l8 = {"FS"}; // double[] d8 = {15}; // double[] dl8 = {5}; // Task t8 = new Task("8",l8,d8,dl8); // String[] l9 = {"SS"}; // double[] d9 = {18}; // double[] dl9 = {20}; // Task t9 = new Task("9",l9,d9,dl9); // String[] l10 = {"FS"}; // double[] d10 = {30}; // double[] dl10 = {0}; // Task t10 = new Task("10",l10,d10,dl10); // String[] l11 = {"FS"}; // double[] d11 = {28}; // double[] dl11 = {5}; // Task t11 = new Task("11",l11,d11,dl11); // String[] l12 = {"FS"}; // double[] d12 = {140}; // double[] dl12 = {0}; // Task t12 = new Task("12",l12,d12,dl12); // String[] l13 = {"FS"}; // double[] d13 = {18}; // double[] dl13 = {-5}; // Task t13 = new Task("13",l13,d13,dl13); // String[] l14 = {"SS"}; // double[] d14 = {20}; // double[] dl14 = {10}; // Task t14 = new Task("14",l14,d14,dl14); // String[] l15 = {"FS"}; // double[] d15 = {15}; // double[] dl15 = {0}; // Task t15 = new Task("15",l15,d15,dl15); // String[] l16 = {"FS"}; // double[] d16 = {33}; // double[] dl16 = {0}; // Task t16 = new Task("16",l16,d16,dl16); // String[] l17 = {"FS"}; // double[] d17 = {8}; // double[] dl17 = {0}; // Task t17 = new Task("17",l17,d17,dl17); // String[] l18 = {"FS"}; // double[] d18 = {15}; // double[] dl18 = {0}; // Task t18 = new Task("18",l18,d18,dl18); // String[] l19 = {"FS"}; // double[] d19 = {17}; // double[] dl19 = {0}; // Task t19 = new Task("19",l19,d19,dl19); // String[] l20 = {"FS"}; // double[] d20 = {25}; // double[] dl20 = {0}; // Task t20 = new Task("20",l20,d20,dl20); // Task t1 = new Task("1","FS",15,0); // Task t2 = new Task("2","FS",20,-5); // Task t3 = new Task("3","FS",26,0); // Task t4 = new Task("4","SS",18,10); // Task t5 = new Task("5","FS",15,0); // Task t6 = new Task("6","FS",38,0); // Task t7 = new Task("7","FS",25,-5); // Task t8 = new Task("8","FS",15,5); // Task t9 = new Task("9","SS",18,20); // Task t10 = new Task("10","FS",30,0); // Task t11 = new Task("11","FS",28,5); // Task t12 = new Task("12","FS",140,0); // Task t13 = new Task("13","FS",18,-5); // Task t14 = new Task("14","SS",20,10); // Task t15 = new Task("15","FS",15,0); // Task t16 = new Task("16","FS",33,0); // Task t17 = new Task("17","FS",8,0); // Task t18 = new Task("18","FS",15,0); // Task t19 = new Task("19","FS",17,0); // Task t20 = new Task("20","FS",25,0); // // List<Task> tl1 = new LinkedList<Task>(); // List<Task> tl2 = new LinkedList<Task>(); // List<Task> tl3 = new LinkedList<Task>(); // List<Task> tl4 = new LinkedList<Task>(); // List<Task> tl5 = new LinkedList<Task>(); // List<Task> tl6 = new LinkedList<Task>(); // List<Task> tl7 = new LinkedList<Task>(); // List<Task> tl8 = new LinkedList<Task>(); // List<Task> tl9 = new LinkedList<Task>(); // List<Task> tl10 = new LinkedList<Task>(); // List<Task> tl11 = new LinkedList<Task>(); // List<Task> tl12 = new LinkedList<Task>(); // List<Task> tl13 = new LinkedList<Task>(); // List<Task> tl14 = new LinkedList<Task>(); // // List<Task> tl = new LinkedList<Task>(); // // tl1.add(t1); // tl2.add(t2); // tl3.add(t4); // tl4.add(t6); // tl5.add(t3); // tl5.add(t5); // tl6.add(t7); // tl6.add(t8); // tl6.add(t9); // tl7.add(t10); // tl8.add(t12); // tl9.add(t13); // tl10.add(t14); // tl11.add(t11); // tl11.add(t15); // tl12.add(t16); // tl13.add(t17); // tl14.add(t18); // tl14.add(t19); // // tl.add(t1); // tl.add(t2); // tl.add(t3); // tl.add(t4); // tl.add(t5); // tl.add(t6); // tl.add(t7); // tl.add(t8); // tl.add(t9); // tl.add(t10); // tl.add(t11); // tl.add(t12); // tl.add(t13); // tl.add(t14); // tl.add(t15); // tl.add(t16); // tl.add(t17); // tl.add(t18); // tl.add(t19); // tl.add(t20); // // // t2.setPreviousTasks(tl1); // t3.setPreviousTasks(tl2); // t4.setPreviousTasks(tl2); // t5.setPreviousTasks(tl3); // t6.setPreviousTasks(tl5); // t7.setPreviousTasks(tl4); // t8.setPreviousTasks(tl4); // t9.setPreviousTasks(tl4); // t10.setPreviousTasks(tl6); // t11.setPreviousTasks(tl7); // // t13.setPreviousTasks(tl8); // t14.setPreviousTasks(tl9); // t15.setPreviousTasks(tl10); // t16.setPreviousTasks(tl11); // t17.setPreviousTasks(tl12); // t18.setPreviousTasks(tl13); // t19.setPreviousTasks(tl13); // t20.setPreviousTasks(tl14); // Wbs wbs = new Wbs(tl); // Set<Task> task = wbs.getNoPreviousTasks(); // for (Task task2 : task) { // System.out.println("taskNumber=nb="+task2.getTaskNumber()); // } // Set<Task> taskt = wbs.getNoNextTasks(); // for (Task task2 : taskt) { // System.out.println("taskNumber=na="+task2.getTaskNumber()); // } // wbs.calculateTime(); // wbs.calculateTimeArray(); // long time1 = System.currentTimeMillis(); // Task previous = new Task("1","FS",15,0); // List<Task> tls = new LinkedList<Task>(); // tls.add(previous); // List<Task> tl = new LinkedList<Task>(); // tl.add(previous); // for(int i = 2;i<=2000;i++){ // Task tmp = new Task(String.valueOf(i),"FS",15,0); // tmp.setPreviousTasks(tls); // tls = new LinkedList<Task>(); // tls.add(tmp); // tl.add(tmp); // } // long time2 = System.currentTimeMillis(); // System.out.println("构建用时:"+(time2-time1)); // Wbs wbs = new Wbs(tl); // wbs.calculateTime(); // long time3 = System.currentTimeMillis(); // System.out.println("计算用时:"+(time3-time2)); //数组的计算 long time1 = System.currentTimeMillis(); int arrayLength = 200; String[] logicarray = new String[arrayLength]; double[] delaytimearray = new double[arrayLength]; double[] durtimearray = new double[arrayLength]; Random random = new Random(); for(int i = 0; i < arrayLength;i++) { //获得200以内的正整数为执行时间数组赋值 durtimearray[i] =Math.abs(random.nextInt())%200; //获得20以内的整数为浮动时间赋值 delaytimearray[i] =Math.abs(random.nextInt()%20); //获得4以内的整数为4种逻辑关系赋值 int index = Math.abs(random.nextInt())%4; switch (index) { case 1: logicarray[i]="SS"; break; case 2: logicarray[i]="FF"; break; case 3: logicarray[i]="SF"; break; default: logicarray[i]="FS"; break; } } Task previous = new Task("task1",logicarray,delaytimearray,durtimearray); List<Task> tls = new LinkedList<Task>(); tls.add(previous); List<Task> tl = new LinkedList<Task>(); tl.add(previous); for(int i = 2;i<=5000;i++){ String[] logicarrayi = new String[arrayLength]; double[] delaytimearrayi = new double[arrayLength]; double[] durtimearrayi = new double[arrayLength]; Random randomi = new Random(); for(int ii = 0; ii < arrayLength;ii++) { //获得200以内的正整数为执行时间数组赋值 durtimearrayi[ii] =Math.abs(randomi.nextInt())%200; //获得20以内的整数为浮动时间赋值 delaytimearrayi[ii] =Math.abs(randomi.nextInt()%20); //获得4以内的整数为4种逻辑关系赋值 int index = Math.abs(randomi.nextInt())%4; switch (index) { case 1: logicarrayi[ii]="SS"; break; case 2: logicarrayi[ii]="FF"; break; case 3: logicarrayi[ii]="SF"; break; default: logicarrayi[ii]="FS"; break; } } Task tmp = new Task("task"+i,logicarrayi,delaytimearrayi,durtimearrayi); tmp.setPreviousTasks(tls); tls = new LinkedList<Task>(); int previousCount = Math.abs(randomi.nextInt())%8; for(int ii = 0; ii < previousCount;ii++) { if(ii<tl.size()){ tls.add(tl.get(ii)); } } tl.add(tmp); } long time2 = System.currentTimeMillis(); System.out.println("构建用时:"+(time2-time1)); Wbs wbs = new Wbs(tl); wbs.calculateTimeArray(); long time3 = System.currentTimeMillis(); System.out.println("计算用时:"+(time3-time2)); } }
发表评论
-
BufferedImage与byte[]互转
2012-06-18 14:51 1021转载自:http://www.cnblogs.com/XL-L ... -
Java定时任务的实现(转)
2011-07-01 10:02 856本例依据Java自身提供的接口实现,通过监听器(Listen ... -
JVM内存管理的基础知识----栈,堆,常量池
2011-06-22 16:09 1611读书笔记: 涉及名词:寄存器,栈,堆,静态域,常量池,非RA ... -
关于jvm的内存限制的问题的解决办法
2010-06-09 14:27 969jdk编译器对内存的支持不同,client状态和server状 ... -
java写的从ftp上找到文件并把文件里的数据插入到数据库的工具类
2010-06-09 14:04 3339因为有个导入数据的需 ... -
jcexporter的jar包
2010-06-09 13:47 785jcexporter都是用java6编译过的,现在反编译了一个 ... -
利用Itext画模板导出word,纯java实现
2010-06-09 13:26 9700最近项目中要用到导出word这个功能,大概研究了一些实现方式。 ... -
应用中引入json时用到的jar包
2010-05-11 17:07 910应用中引入json时用到的jar包 -
java调用web2pic实现整站页面截屏(只能windows)
2010-05-11 16:49 1676java调用web2pic实现截屏(只能windows) -
重构-改善既有代码的设计
2010-02-25 16:39 782重构-改善既有代码的设计(繁体中文版) -
javaEE学习笔记
2010-01-22 12:51 889javaEE学习笔记
相关推荐
针对项目管理中关键路径计算这个核心问题,分析了关键路径算法的传统解决方式,深入研究了面向对象方式下解决这个问题的方法,给出了完整、洁净的解决方案,对用面向对象方式解决其他经典问题有帮助。
有良好界面的JAVA编写的AOE网络求取关键路径,比较完善
设计和实现了关键路径问题的算法,通过拓扑排序得到图形的关键路径,使用的编程语言是java。
简单介绍图的结构建立与最短路径算法,不是源代码
该程序(cpm)是关键路径法算法的实现,该算法可以以最小的总成本和最佳的持续时间来计划一组项目活动。 建筑学 核心组件是cpm.py模块。 该模块实现了关键路径方法算法,旨在用作库。 有两个使用cpm.py模块的用户...
主要为大家详细介绍了Java实现Floyd算法求最短路径,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
蚁群算法实现:利用Java编程语言实现蚁群算法,用于模拟蚂蚁在网络拓扑中的移动和信息传递过程。蚁群算法的关键在于蚂蚁的行为规则和信息素更新策略,需要合理设计和实现这些部分。 路由选择策略:设计路由选择策略...
(5)关键路径 (6)单源最短路径 5.散列表(哈希表) (1)散列表的概念 (2)散列表解决散列冲突的方法(开放地址法、链地址法) (3)散列表的插入和删除 6.算法分析与设计基础 (1)分治与递归的关系 (2)...
在项目中,用户可以直观地观察到蚁群算法在解决路由选择问题过程中的动态变化,包括路径选择、信息素更新等关键步骤。此外,项目还提供了丰富的参数设置功能,允许用户根据实际需求调整算法参数,以获得更好的模拟...
CART算法的全称是分类回归树算法,他是一个二元分类,采用的是类似于熵的基尼指数作为分类决策,形成决策树后之后还要进行剪枝,我自己在实现整个算法的时候采用的是代价复杂度算法,详细介绍链接 KNN K最近邻算法...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
每千次展示费用关键路径法(或关键路径分析),使用它来进行关键路径分析。 在其他开放源代码项目(例如JUNG,Joda-Time和DateCalc)的帮助下用Java编写。
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
简单 Java图片加水印,支持旋转和透明度设置 摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,...
校园导游系统,顾名思义,是为了便于来访者对校园景点环境及路径查询的服务系统,在保证查询校园景点信息(配图)的同时,该系统关键部分是路径查询,学校所以主要景点连接起来正是无向有权图,选定最短路径算法,则从...
简单 Java图片加水印,支持旋转和透明度设置 摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,...