Java 编写 PERT 关于 “软件过程管理里的项目预期”的算法实现-【经过设计模式改造和算法优化】
日期:2020.03.07
博客期:163
星期六
【博客前言】
继续上回博客的内容补充PERT的相关运算,实现语言为 Java 语言。和上次一样,整个博客的结构也都是一样!先说明一下啊,在写本次博客的时候我还不知道老师要求的看的那个函数究竟是个什么函数。这次实际上用到了上次博客的 几个工具类或基础类,但是做到一半的时候发现这两个不兼容。通过这个练习吧,我觉得自己完全掌握 软件过程管理 PERT 部分的题了。
【实装代码】
引用上次代码:
com.imp.cmp.tool 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.tool; 2 3 //--------------------------- 4 //---【遍历工具】 5 //-- 6 //- 7 // 8 public class VisitedTool { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //存储区 11 private int [] jer; 12 //长度 13 private int leng; 14 //-------------------------------------<方法成员>-------------------------------------// 15 //-- 16 //---[基本方法] 17 public boolean isAllAccess() { 18 19 for(int i=0;i<leng;++i) 20 if(jer[i]==0) 21 return false; 22 23 return true; 24 } 25 //设置某一项可以通过 26 public void set(int x) { 27 if(x>=0&&x<this.leng) 28 this.jer[x] = 1; 29 30 } 31 //访问是否已经访问 32 public boolean isVisited(int x){ 33 return this.jer[x]!=0; 34 } 35 //重新设置 36 public void reset() { 37 this.jer = new int [this.leng]; 38 for(int i=0;i<this.leng;++i) 39 jer[i] = 0; 40 } 41 public void reset(int leng) { 42 this.leng = leng; 43 this.jer = new int [leng]; 44 for(int i=0;i<leng;++i) 45 jer[i] = 0; 46 } 47 //---[构造方法] 48 public VisitedTool(int leng) { 49 this.leng = leng; 50 this.jer = new int [leng]; 51 for(int i=0;i<leng;++i) 52 jer[i] = 0; 53 } 54 55 }
com.imp.cmp.node 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.cmp.node; 2 3 //--------------------------- 4 //---【节点类】 5 //-- 6 //- 7 // 8 public abstract class Node { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //结点描述 11 protected String chara; 12 //-------------------------------------<方法成员>-------------------------------------// 13 //-- 14 //---[set、get方法] 15 //get 16 public String getChara() { 17 return chara; 18 } 19 //set 20 public void setChara(String chara) { 21 this.chara = chara; 22 } 23 //---[构造方法] 24 public Node() { 25 super(); 26 this.chara = ""; 27 } 28 public Node(String chara) { 29 super(); 30 this.chara = chara; 31 } 32 //---[附加方法] 33 //因实际类型可复制,所以可以获取实际值 34 public abstract double getTime(); 35 }
本次更新代码:
com.imp.pert 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert; 2 3 import java.util.Scanner; 4 5 //--------------------------- 6 //---【主程序】 7 //-- 8 //- 9 // 10 public class Client { 11 //-------------------------------------<内部成员>-------------------------------------// 12 //-- 13 //---[真实成员] 14 //输入器 15 protected Scanner sc; 16 //控制器 17 protected Controler con; 18 //视图控件 19 protected PERTViewer v; 20 //---[临时成员] 21 //读取内容 22 private String tmp; 23 //-------------------------------------<方法成员>-------------------------------------// 24 //-- 25 //---[包装方法] 26 //开始 27 public void start() { 28 this.sc_get_node(); 29 this.sc_get_line(); 30 this.deal(); 31 this.stop(); 32 } 33 //结束 34 private void stop() { 35 this.sc.close(); 36 } 37 //输入node部分 38 private void sc_get_node() { 39 this.print_first_tip(); 40 41 this.tmp = this.sc.nextLine(); 42 while(this.tmp.compareTo("#END#")!=0) 43 { 44 int code = Integer.parseInt(this.tmp); 45 46 this.con.addSimpleNode(code); 47 48 this.tmp = sc.nextLine(); 49 } 50 51 this.print_ok(); 52 } 53 //输入line部分 54 private void sc_get_line() { 55 this.print_second_tip(); 56 57 this.tmp = sc.nextLine(); 58 59 while(this.tmp.compareTo("#END#")!=0) 60 { 61 String [] sg = this.tmp.split(","); 62 63 String chara = sg[0]; 64 65 double opti = Double.parseDouble(sg[1]); 66 67 double pess = Double.parseDouble(sg[2]); 68 69 double poss = Double.parseDouble(sg[3]); 70 71 int start = Integer.parseInt(sg[4]); 72 73 int end = Integer.parseInt(sg[5]); 74 75 this.con.addLinkedLine(opti, pess, poss, chara , start ,end); 76 77 this.tmp = this.sc.nextLine(); 78 } 79 80 this.print_ok(); 81 } 82 //处理部分 83 private void deal() { 84 this.v.display_lines(this.con.llg); 85 this.con.build(); 86 System.out.println(""); 87 System.out.println(""); 88 this.v.display_nodes(this.con.sng); 89 System.out.println(""); 90 } 91 //---[输出部分] 92 //打印第一个提示部分 93 private void print_first_tip() { 94 System.out.println(""); 95 System.out.println(" #: Please scanner the temp code ... "); 96 System.out.println(" print example: 1"); 97 System.out.println(" end with: #END# "); 98 System.out.println(""); 99 System.out.println(""); 100 } 101 //打印第二个提示部分 102 private void print_second_tip() { 103 System.out.println(""); 104 System.out.println(" #: Please scanner the activity ... "); 105 System.out.println(" print example: A,3,6,4,0,1"); 106 System.out.println(" sort by : chara , opti , pess , poss , start , end "); 107 System.out.println(" end with: #END# "); 108 System.out.println(""); 109 } 110 //打印程序就绪状态 111 private void print_ok() { 112 System.out.println(""); 113 System.out.println(" @: OK"); 114 System.out.println(""); 115 } 116 //---[建造模式] 117 //构造方法 118 public Client() { 119 this.sc = new Scanner(System.in); 120 this.con = new Controler(); 121 this.v = new PERTViewer(); 122 this.tmp = ""; 123 } 124 //测试 125 public static void main(String[] args) { 126 Client client = new Client(); 127 client.start(); 128 } 129 } 130 //测试用例: 131 /* 132 1 133 2 134 3 135 4 136 5 137 6 138 #END# 139 A,5,8,6,1,2 140 B,3,5,4,1,3 141 C,2,3,3,2,4 142 D,3.5,5,4,3,4 143 E,1,4,3,3,5 144 F,8,15,10,1,5 145 G,2,4,3,5,6 146 H,2,2.5,2,4,6 147 #END# 148 */
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert; 2 3 import com.imp.cmp.tool.VisitedTool; 4 import com.imp.pert.line.LinkedLine; 5 import com.imp.pert.line.LinkedLineGroup; 6 import com.imp.pert.node.SimpleNode; 7 import com.imp.pert.node.SimpleNodeGroup; 8 9 //--------------------------- 10 //---【控制类】 11 //-- 12 //- 13 // 14 public class Controler { 15 //-------------------------------------<内部成员>-------------------------------------// 16 //连线集合 17 protected LinkedLineGroup llg; 18 //结点集合 19 protected SimpleNodeGroup sng; 20 //-------------------------------------<方法成员>-------------------------------------// 21 //-- 22 //---[集合添加] 23 //添加一个连线 24 public void addLinkedLine(double a,double b,double m,String chara) { 25 this.llg.add(new LinkedLine(chara,a,b,m)); 26 } 27 public void addLinkedLine(double a,double b,double m,String chara,int start,int end) { 28 LinkedLine ll = new LinkedLine(chara,a,b,m); 29 ll.set_s(start); 30 ll.set_e(end); 31 this.llg.add(ll); 32 } 33 public void addSimpleNode(int code) { 34 this.sng.add(new SimpleNode(code)); 35 } 36 //---[建立] 37 public void build() { 38 this.build_data(); 39 } 40 private void build_data() { 41 int leng = this.sng.size(); 42 43 VisitedTool vt = new VisitedTool(leng); 44 45 while(!vt.isAllAccess()) 46 { 47 for(int i=0;i<leng;++i) 48 this.build_data(this.sng.get(i).getCode(), vt); 49 } 50 } 51 private void build_data(int code,VisitedTool vt) { 52 53 if(!vt.isVisited(this.sng.indexOf(code))) 54 { 55 LinkedLineGroup llgs = this.llg.select_end_equals(code); 56 57 int leng = llgs.size(); 58 59 if(leng==0) 60 { 61 //如果是 0 ,就是最开始的结点,执行赋值 62 SimpleNode sns = this.sng.getIn(code); 63 sns.setSta_dis(0.0); 64 sns.setExp_term(0.0); 65 this.sng.setIn(code, sns); 66 vt.set(this.sng.indexOf(code)); 67 } 68 else 69 { 70 double s = 0.0; 71 double t = 0.0; 72 73 for(int i=0;i<leng;++i) 74 { 75 int start = llgs.get(i).getLS().start; 76 if(!vt.isVisited(this.sng.indexOf(start))) 77 return; 78 LinkedLine ll = llgs.get(i); 79 80 double ps = Math.sqrt(ll.get_star_dis()*ll.get_star_dis()+this.sng.getIn(start).getSta_dis()*this.sng.getIn(start).getSta_dis()); 81 double pt = ll.get_expe_term() + this.sng.getIn(start).getExp_term(); 82 83 ps = (double) Math.round(ps * 100) / 100; 84 pt = (double) Math.round(pt * 100) / 100; 85 86 if(s < ps) 87 s = ps; 88 if(t < pt) 89 t = pt; 90 } 91 92 SimpleNode sn = this.sng.getIn(code); 93 sn.setSta_dis(s); 94 sn.setExp_term(t); 95 this.sng.setIn(code, sn); 96 vt.set(this.sng.indexOf(code)); 97 } 98 } 99 100 } 101 //---[构造方法] 102 public Controler() { 103 super(); 104 // TODO Auto-generated constructor stub 105 this.llg = new LinkedLineGroup(); 106 this.sng = new SimpleNodeGroup(); 107 } 108 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert; 2 3 import com.imp.pert.line.LinkedLine; 4 import com.imp.pert.line.LinkedLineGroup; 5 import com.imp.pert.node.SimpleNode; 6 import com.imp.pert.node.SimpleNodeGroup; 7 8 //--------------------------- 9 //---【视图控件】 10 //-- 11 //- 12 // 13 public class PERTViewer { 14 //展示连线信息 15 public void display_lines(LinkedLineGroup llg) { 16 int leng = llg.size(); 17 System.out.println(); 18 System.out.println("chara\topti\tpess\tposs\texp_te\tsta_dis\tstart\tend\t"); 19 for(int i=0;i<leng;++i) 20 { 21 LinkedLine ll = llg.get(i); 22 System.out.println(ll.getChara()+"\t"+ll.getOpti_term()+"\t"+ll.getPess_term()+"\t"+ll.getPoss_term()+"\t"+ll.get_expe_term()+"\t"+ll.get_star_dis()+"\t"+ll.getLS().start+"\t"+ll.getLS().end); 23 } 24 System.out.println(); 25 } 26 //展示结点信息 27 public void display_nodes(SimpleNodeGroup sng) { 28 int leng = sng.size(); 29 System.out.println(); 30 System.out.println("code\texp_te\tsta_dis"); 31 for(int i=0;i<leng;++i) 32 { 33 SimpleNode sn = sng.get(i); 34 System.out.println(sn.getCode()+"\t"+sn.getExp_term()+"\t"+sn.getSta_dis()); 35 } 36 System.out.println(); 37 } 38 //构造 39 public PERTViewer() { 40 // Do Nothing ... 41 } 42 }
com.imp.pert.tool 包:(这个类没有使用上,因为不确定那个确立图是否为部分三角函数)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert.tool; 2 3 //计算类 4 public class MultiGetDesi { 5 // f(x) = - 50 sin( x * 2.0 * pai / 13.0 ) + 100 6 public static int getImComplete(double x) { 7 double p = x * 2.0 * Math.PI / 13.0; 8 p = Math.sin(p); 9 p = 50 - 50 * p; 10 return (int)p; 11 } 12 // f-1(x) - AntiFun 13 public static double getAntiComplete(int x) { 14 x = 50 - x; 15 double p = ((double)x)/50.0; 16 p = Math.asin(p); 17 p = p * 13.0; 18 p = p / 2.0; 19 p = p / Math.PI; 20 return p; 21 } 22 public static void main(String[] args) { 23 System.out.println("f(-3.25) = "+getImComplete(-3.25)); 24 System.out.println("f(-1.5) = "+getImComplete(-1.5)); 25 System.out.println("f(0) = "+getImComplete(0)); 26 System.out.println("f(+1.5) = "+getImComplete(1.5)); 27 System.out.println("f(+3.25) = "+getImComplete(3.25)); 28 } 29 }
com.imp.pert.line 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert.line; 2 3 /*图表信息结构体*/ 4 //- 5 public class LineStruct { 6 public int start; 7 public int end; 8 public LineStruct(int a,int b) { 9 this.start = a; 10 this.end = b; 11 } 12 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert.line; 2 3 import com.imp.cmp.node.Node; 4 5 //--------------------------- 6 //---【活动-结点连线】 7 //-- 8 //- 9 // 10 public class ActiviteLine extends Node { 11 //-------------------------------------<内部成员>-------------------------------------// 12 //乐观的周期 13 protected double opti_term; 14 //悲观的周期 15 protected double pess_term; 16 //最可能的周期 17 protected double poss_term; 18 //-------------------------------------<方法成员>-------------------------------------// 19 //-- 20 //---[set、get方法] 21 //opti 22 public double getOpti_term() { 23 return opti_term; 24 } 25 public void setOpti_term(double opti_term) { 26 this.opti_term = opti_term; 27 } 28 //pess 29 public double getPess_term() { 30 return pess_term; 31 } 32 public void setPess_term(double pess_term) { 33 this.pess_term = pess_term; 34 } 35 //poss 36 public double getPoss_term() { 37 return poss_term; 38 } 39 public void setPoss_term(double poss_term) { 40 this.poss_term = poss_term; 41 } 42 //---[其余方法] 43 //获取期望的周期 44 public double get_expe_term() { 45 double d = (this.opti_term+this.pess_term+this.poss_term*4.0)/6.0;; 46 return (double) Math.round(d * 100) / 100; 47 } 48 //获取标准偏差 49 public double get_star_dis() { 50 double d = (this.pess_term-this.opti_term)/6.0; 51 return (double) Math.round(d * 100) / 100; 52 } 53 //---[复写方法] 54 @Override 55 public double getTime() { 56 // TODO Auto-generated method stub 57 return this.get_expe_term(); 58 } 59 //---[构造方法] 60 public ActiviteLine() { 61 super(); 62 // TODO Auto-generated constructor stub 63 } 64 public ActiviteLine(String chara) { 65 super(chara); 66 // TODO Auto-generated constructor stub 67 } 68 public ActiviteLine(double opti_term, double pess_term, double poss_term) { 69 super(); 70 this.opti_term = opti_term; 71 this.pess_term = pess_term; 72 this.poss_term = poss_term; 73 } 74 public ActiviteLine(String chara,double opti_term, double pess_term, double poss_term) { 75 super(chara); 76 this.opti_term = opti_term; 77 this.pess_term = pess_term; 78 this.poss_term = poss_term; 79 } 80 //测试 81 public static void main(String[] args) { 82 ActiviteLine ln = new ActiviteLine("A",5.0,8.0,6.0); 83 System.out.println(ln.getTime()+"\t"+ln.get_star_dis()); 84 } 85 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert.line; 2 3 //--------------------------- 4 //---【活动-结点连线+图表信息】 5 //-- 6 //- 7 // 8 public class LinkedLine extends ActiviteLine { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //连接表信息 11 protected LineStruct ls; 12 //-------------------------------------<方法成员>-------------------------------------// 13 //-- 14 //---[建立LineStruct] 15 //初始化 16 private void init() { 17 this.ls = new LineStruct(0,0); 18 } 19 //设值 20 public void set_s(int start) { 21 this.ls.start = start; 22 } 23 public void set_e(int end) { 24 this.ls.end = end; 25 } 26 //获取 27 public LineStruct getLS() { 28 return this.ls; 29 } 30 //---[构造方法] 31 public LinkedLine() { 32 super(); 33 // TODO Auto-generated constructor stub 34 this.init(); 35 } 36 public LinkedLine(double opti_term, double pess_term, double poss_term) { 37 super(opti_term, pess_term, poss_term); 38 // TODO Auto-generated constructor stub 39 this.init(); 40 } 41 public LinkedLine(String chara, double opti_term, double pess_term, double poss_term) { 42 super(chara, opti_term, pess_term, poss_term); 43 // TODO Auto-generated constructor stub 44 this.init(); 45 } 46 public LinkedLine(String chara) { 47 super(chara); 48 // TODO Auto-generated constructor stub 49 this.init(); 50 } 51 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert.line; 2 3 import java.util.ArrayList; 4 5 //--------------------------- 6 //---【活动-结点连线+图表信息 组】 7 //-- 8 //- 9 // 10 public class LinkedLineGroup extends ArrayList <LinkedLine>{ 11 //串行标识 12 private static final long serialVersionUID = 1L; 13 //索引位置 14 public int indexOf(String chara) { 15 int leng = super.size(); 16 17 for(int i=0;i<leng;++i) 18 { 19 if(super.get(i).getChara().compareTo(chara)==0) 20 return i; 21 } 22 23 return -1; 24 } 25 //起始索引 26 public LinkedLineGroup select_start_equals(int start) { 27 LinkedLineGroup llg = new LinkedLineGroup(); 28 29 int leng = super.size(); 30 31 for(int i=0;i<leng;++i) 32 { 33 LinkedLine ll = super.get(i); 34 if(ll.getLS().start==start) 35 llg.add(ll); 36 } 37 38 return llg; 39 } 40 //起始索引 41 public LinkedLineGroup select_end_equals(int end) { 42 LinkedLineGroup llg = new LinkedLineGroup(); 43 44 int leng = super.size(); 45 46 for(int i=0;i<leng;++i) 47 { 48 LinkedLine ll = super.get(i); 49 if(ll.getLS().end==end) 50 llg.add(ll); 51 } 52 53 return llg; 54 } 55 //索引数据 56 public LinkedLine get(String chara) { 57 int seat = this.indexOf(chara); 58 59 return (seat!=-1)?super.get(seat):null; 60 } 61 //索引替换 62 public void set(String chara,LinkedLine ll) { 63 int seat = this.indexOf(chara); 64 65 if(seat!=-1) 66 super.set(seat, ll); 67 } 68 //构造方法 69 public LinkedLineGroup() { 70 super(); 71 // TODO Auto-generated constructor stub 72 } 73 }
com.imp.pert.node 包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert.node; 2 3 //--------------------------- 4 //---【活动间隔节点】 5 //-- 6 //- 7 // 8 public class SimpleNode { 9 //-------------------------------------<内部成员>-------------------------------------// 10 //结点编码 11 protected int code; 12 //期望到达周期 13 protected double exp_term; 14 //标准偏差 15 protected double sta_dis; 16 //-------------------------------------<方法成员>-------------------------------------// 17 //-- 18 //---[set、get方法] 19 //get 20 public int getCode() { 21 return code; 22 } 23 public double getExp_term() { 24 return exp_term; 25 } 26 public double getSta_dis() { 27 return sta_dis; 28 } 29 //set 30 public void setExp_term(double exp_term) { 31 this.exp_term = exp_term; 32 } 33 public void setSta_dis(double sta_dis) { 34 this.sta_dis = sta_dis; 35 } 36 //计算 z 值 37 public double getZ(double t) { 38 double d = (t - this.exp_term)/this.sta_dis;; 39 return (double) Math.round(d * 100) / 100; 40 } 41 //---[构造方法] 42 public SimpleNode(int code) { 43 super(); 44 // TODO Auto-generated constructor stub 45 this.code = code; 46 this.exp_term = 0.0; 47 this.sta_dis = 0.0; 48 } 49 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.imp.pert.node; 2 3 import java.util.ArrayList; 4 5 public class SimpleNodeGroup extends ArrayList<SimpleNode>{ 6 //串行标识 7 private static final long serialVersionUID = 1L; 8 //构造方法 9 public SimpleNodeGroup() { 10 super(); 11 // TODO Auto-generated constructor stub 12 } 13 //获取索引 14 public int indexOf(int code) { 15 int leng = super.size(); 16 17 for(int i=0;i<leng;++i) 18 { 19 if(this.get(i).code==code) 20 return i; 21 } 22 23 return -1; 24 } 25 //获取元素 26 public SimpleNode getIn(int code) { 27 int seat = this.indexOf(code); 28 29 if(seat==-1) 30 return null; 31 32 return super.get(seat); 33 } 34 //设值元素 35 public void setIn(int code,SimpleNode sn) { 36 int seat = this.indexOf(code); 37 38 if(seat!=-1) 39 { 40 super.set(seat, sn); 41 } 42 } 43 }
【项目结构图】
【类图】
【使用到的设计模式】
1、MVC模式:很明显 Viewer 和 Controler 是对应 V 和 C ,而 M 将由 “Node” 和 “” 来对应 。
2、外观模式: 使用Client类,将整个程序的执行分成了四部分,也就是四个子系统,对这四个子系统的统一调用是属于外观模式的。
3、适配器模式:这一会是吸取教训,直接做成了 LinkedLine 继承 ActiveLine ,并且关联 LineStruct ,来实现多继承的关系。
【测试】
由于特殊原因,本次提供单一的测试用例:
输入用例:
1 2 3 4 5 6 #END# A,5,8,6,1,2 B,3,5,4,1,3 C,2,3,3,2,4 D,3.5,5,4,3,4 E,1,4,3,3,5 F,8,15,10,1,5 G,2,4,3,5,6 H,2,2.5,2,4,6 #END#
输出结果:
【测试图中的表与之对应的中文释义】
PS:博客园有毒,每一次我都是在前一天发表的,等到看它发表完,就是第二天 0点了,已经有两次这样了。