Java 编写 PERT 关于 “软件过程管理里的项目预期”的算法实现-【经过设计模式改造和算法优化】

日期:2020.03.07

博客期:163

星期六

  【博客前言

    继续上回博客的内容补充PERT的相关运算,实现语言为 Java 语言。和上次一样,整个博客的结构也都是一样!先说明一下啊,在写本次博客的时候我还不知道老师要求的看的那个函数究竟是个什么函数。这次实际上用到了上次博客的 几个工具类或基础类,但是做到一半的时候发现这两个不兼容。通过这个练习吧,我觉得自己完全掌握 软件过程管理 PERT 部分的题了。

  【实装代码

   引用上次代码:

    com.imp.cmp.tool 包:

 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 }
VisitedTool.java

    com.imp.cmp.node 包:

 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 }
Node.java

  本次更新代码:

    com.imp.pert 包:

  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 */
Client.java
  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 }
Controler.java
 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	opti	pess	poss	exp_te	sta_dis	start	end	");
19         for(int i=0;i<leng;++i)
20         {
21             LinkedLine ll = llg.get(i);
22             System.out.println(ll.getChara()+"	"+ll.getOpti_term()+"	"+ll.getPess_term()+"	"+ll.getPoss_term()+"	"+ll.get_expe_term()+"	"+ll.get_star_dis()+"	"+ll.getLS().start+"	"+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	exp_te	sta_dis");
31         for(int i=0;i<leng;++i)
32         {
33             SimpleNode sn = sng.get(i);
34             System.out.println(sn.getCode()+"	"+sn.getExp_term()+"	"+sn.getSta_dis());
35         }
36         System.out.println();
37     }
38     //构造
39     public PERTViewer() {
40         // Do Nothing ...
41     }
42 }
PERTViewer.java

    com.imp.pert.tool 包:(这个类没有使用上,因为不确定那个确立图是否为部分三角函数)

 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 }
MultiGetDesi.java

    com.imp.pert.line 包:

 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 }
LineStruct.java
 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()+"	"+ln.get_star_dis());
84     }
85 }
ActiviteLine.java
 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 }
LinkedLine.java
 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 }
LinkedLineGroup.java

    com.imp.pert.node 包:

 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 }
SimpleNode.java
 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 }
SimpleNodeGroup.java

  【项目结构图

 

  【类图

 

  【使用到的设计模式

     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点了,已经有两次这样了。

原文地址:https://www.cnblogs.com/onepersonwholive/p/12439382.html