diff --git a/ym-quality-planning/src/main/java/com/cnbm/qualityPlanning/common/StatisticalControlledTest.java b/ym-quality-planning/src/main/java/com/cnbm/qualityPlanning/common/StatisticalControlledTest.java index fd4b2f6..632d866 100644 --- a/ym-quality-planning/src/main/java/com/cnbm/qualityPlanning/common/StatisticalControlledTest.java +++ b/ym-quality-planning/src/main/java/com/cnbm/qualityPlanning/common/StatisticalControlledTest.java @@ -1,13 +1,12 @@ package com.cnbm.qualityPlanning.common; + import com.cnbm.qualityPlanning.entity.ControlLimit; +import com.cnbm.qualityPlanning.entity.ControlLimitDetail; import com.cnbm.qualityPlanning.entity.Point; import io.swagger.models.auth.In; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @Desc: "检测参数统计受控 检验类" @@ -27,18 +26,18 @@ public class StatisticalControlledTest { private static final Integer rule10Number = 10; public static List createData(){ - Point point = new Point(1,new Double(1)); - Point point2 = new Point(2,new Double(2)); - Point point3 = new Point(3,new Double(3)); - Point point4 = new Point(4,new Double(4)); - Point point5 = new Point(5,new Double(5)); - Point point6 = new Point(6,new Double(6)); - Point point7 = new Point(7,new Double(7)); - Point point8 = new Point(8,new Double(8)); - Point point9 = new Point(9,new Double(9)); - Point point10 = new Point(10,new Double(10)); - Point point11 = new Point(11,new Double(11)); - Point point12 = new Point(12,new Double(12)); + Point point = new Point(1,new Double(1.7)); + Point point2 = new Point(2,new Double(8)); + Point point3 = new Point(3,new Double(8)); + Point point4 = new Point(4,new Double(1.7)); + Point point5 = new Point(5,new Double(1.7)); + Point point6 = new Point(6,new Double(1.7)); //3 + Point point7 = new Point(7,new Double(1.7)); //3 + Point point8 = new Point(8,new Double(1.7)); //3 //3 + Point point9 = new Point(9,new Double(1.7)); + Point point10 = new Point(10,new Double(1.7)); + Point point11 = new Point(11,new Double(1.7)); + Point point12 = new Point(12,new Double(1.7)); List list = new ArrayList<>(); list.add(point); list.add(point2); @@ -58,33 +57,60 @@ public class StatisticalControlledTest { public static void main(String[] args) { List list = createData(); ControlLimit controlLimit = new ControlLimit(new Double(12),new Double(2),new Double(1)); - - //TEST FOR RULE1 - Boolean aBoolean1 = rule1(list, controlLimit); - +// +// //TEST FOR RULE1 +// Boolean aBoolean1 = rule1(list, controlLimit); +// //TEST FOR RULE2 Boolean aBoolean2 = rule2(list, controlLimit, 9); System.out.println(); - - - //TEST FOR RULE3 - Boolean aBoolean3 = rule3(list, 3); +// +// +// //TEST FOR RULE3 +// Boolean aBoolean3 = rule3(list, 3); +// System.out.println(); +// +// +// //TEST FOR RULE4 +// Boolean aBoolean4 = rule4(list, 4); +// System.out.println(); + +// //TEST FOR RULE5 +// Boolean aBoolean5 = rule5(list, controlLimit, 3,2); +// System.out.println(); + +// //TEST FOR RULE6 +// Boolean aBoolean6 = rule6(list, controlLimit, 3,2); +// System.out.println(); + + //TEST FOR RULE7 + //LC0 = 1.6666 ;; UC1 = 5 + Boolean aBoolean7 = rule7(list, controlLimit,7); System.out.println(); + +// int[] array={1,2,3,4,5,6}; +// int[] ret=new int[3]; +// System.arraycopy(array,0,ret,0,3); +// System.out.println(Arrays.toString(ret)); } /** * name : 规则1 * desc : 控制图上有 1 个点位于三倍标准差以外(对中心线来说)(母体的 $\sigma$ ) - * - * return : 返回的 就是不满足 规则1 的点。 + * 注意: 如果存在满足rule1的点,会在原数组 Point.unsatisfiedRules 里标注出来。 + * return : + * 存在满足rule1的点 => true + * 不存在满足rule1的点 => false * */ private static Boolean rule1(List data, ControlLimit controlLimit){ + Boolean flag = false; for(Point i:data){ if(i.getValue() > controlLimit.getUCL() || i.getValue() < controlLimit.getLCL()){ - i.getUnsatisfiedRules().add(1); + i.getUnsatisfiedRules().add(rule1Number); + flag = true; } } - return true; + return flag; } private static void markUnsatisfiedRulesByKeys(List data,List keys,Integer ruleNumber){ @@ -96,8 +122,11 @@ public class StatisticalControlledTest { /** * name : 规则2 * desc : 连续 n 点落在中心线的用一侧 (默认:9) - * - * return : 返回的 就是不满足 规则2 的点。 + * 注意: 如果存在满足rule2的点,会在原数组 Point.unsatisfiedRules 里标注出来。 + * //todo 存在bug while((upi+1) < data.size()){ ,最后一个点轮询不到 + * return : + * 存在满足rule2的点 => true + * 不存在满足rule2的点 => false * */ private static Boolean rule2(List data, ControlLimit controlLimit,Integer n){ List upList = new ArrayList<>(); @@ -113,13 +142,19 @@ public class StatisticalControlledTest { //上侧的情况 Integer upi = 0; Integer uptime = 0; + Integer upTotalSize = upList.size(); //标注不合格的 参数 List forMarkPoints = new ArrayList<>(); + while((upi+1) < upList.size()){ //if((upList.get(upi).getPosition()+1)==upList.get(upi+1).getPosition()){ if(isBetween(upList.get(upi),upList.get(upi+1))){ uptime +=1; forMarkPoints.add(upList.get(upi)); + if((upi+1)==upTotalSize){ + uptime +=1; + forMarkPoints.add(upList.get(upi+1)); + } //只要到达n 了,就return,防止中间段到达 后面又被重置了 if(uptime>=n){ //1. @@ -138,6 +173,7 @@ public class StatisticalControlledTest { } }else { forMarkPoints = new ArrayList<>(); + upTotalSize-=1; uptime = 0; } upi++; @@ -147,11 +183,16 @@ public class StatisticalControlledTest { //下侧的情况 Integer downi = 0; Integer downtime = 0; + Integer totalSize = downList.size(); forMarkPoints = new ArrayList<>(); while((downi+1) < downList.size()){ - if(isBetween(downList.get(upi),downList.get(upi+1))){ + if(isBetween(downList.get(downi),downList.get(downi+1))){ downtime +=1; forMarkPoints.add(downList.get(downi)); + if((downi+1)==totalSize){ + downtime++; + forMarkPoints.add(downList.get(downi+1)); + } if(downtime>=n){ for (Point key:forMarkPoints){ @@ -166,6 +207,7 @@ public class StatisticalControlledTest { return true; } }else { + totalSize-=1; forMarkPoints = new ArrayList<>(); downtime = 0; } @@ -179,8 +221,10 @@ public class StatisticalControlledTest { /** * name : 规则3 * desc : 连续 n 点递增或者递减 (默认:6) - * - * return : 返回的 就是不满足 规则2 的点。 + * 注意: 如果存在满足rule3的点,会在原数组 Point.unsatisfiedRules 里标注出来。 + * return : + * 存在满足rule3的点 => true + * 不存在满足rule3的点 => false * */ private static Boolean rule3(List data, Integer n){ @@ -232,6 +276,257 @@ public class StatisticalControlledTest { return false; } + /** + * name : 规则4 + * desc : 连续 n 点中 相邻点 交替上下 ( 默认:14 ) + * 注意: 如果存在满足rule4的点,会在原数组 Point.unsatisfiedRules 里标注出来。 + * //todo 有bug while((upi+1) < data.size()) 这里 upi+1 会存在问题 + * return : + * 存在满足rule4的点 => true + * 不存在满足rule4的点 => false + * */ + private static Boolean rule4(List data, Integer n){ + Integer upi = 0; + Boolean current; + Boolean nextNeeded; + Integer times = 0; + List forMarkKey = new ArrayList<>(); + if(isSmall(data.get(0),data.get(1))){ + current = true; + nextNeeded = true; + }else { + current = false; + nextNeeded = false; + } + + while((upi+1) < data.size()){ + if(isBetween( data.get(upi),data.get(upi+1) )){ + //A-B<0 True + //A-B>0 False + if(isSmall(data.get(upi),data.get(upi+1))){ + current = true; + }else { + current = false; + } + + + if (current.equals(nextNeeded)){ + times++; + forMarkKey.add(upi); + if(times == n){ + for(Integer key:forMarkKey){ + data.get(key).getUnsatisfiedRules().add(rule4Number); + } + return true; + } + }else { + times=0; + forMarkKey = new ArrayList<>(); + } + nextNeeded = !current; + }else { + times = 0; + forMarkKey = new ArrayList<>(); + } + upi++; + } + + return false; + } + + /** + * name : 规则5 + * desc : 连续 m 点中 有 n 点 落在中心线同一侧,B区以外。( 默认 m:3 , n:2 ) + * 注意: 如果存在满足rule5的点,会在原数组 Point.unsatisfiedRules 里标注出来。 + * return : + * 存在满足rule5的点 => true + * 不存在满足rule5的点 => false + * */ + private static Boolean rule5(List data,ControlLimit controlLimit, Integer m, Integer n){ + Integer upi = 0; + List upforMarkKey = new ArrayList<>(); + List downforMarkKey = new ArrayList<>(); +// Double[] dataArray = (Double[])data.toArray(); + Object[] dataArray = data.toArray(); + ControlLimitDetail controlLimitDetail = new ControlLimitDetail(controlLimit.getUCL(), controlLimit.getCL(), controlLimit.getLCL()); + System.out.println("controlLimitDetail : "+controlLimitDetail.toString()); + Boolean lastFlag = false; + while(upi < data.size()){ + Point[] keyList = new Point[m]; + if(m>=(data.size()-upi)){ + if(lastFlag){ + break; + } + //System.arraycopy(dataArray , 10 , keyList , 0 , 2 ); + System.arraycopy(dataArray,upi,keyList,0,(data.size()-upi)); + lastFlag = true; + }else { + System.arraycopy(dataArray,upi,keyList,0,m); + } + + Integer upTimes = 0; + Integer downTimes = 0; + for(Point i:keyList){ + if(i.getValue()>controlLimitDetail.getUB()[1]){ + upTimes++; + upforMarkKey.add(i); + System.out.println(); + } + if(i.getValue()=n || downTimes>=n){ + if(upTimes>=n){ + for(Point i:upforMarkKey){ + i.getUnsatisfiedRules().add(rule5Number); + } + return true; + } + if(downTimes>=n){ + for(Point i:downforMarkKey){ + i.getUnsatisfiedRules().add(rule5Number); + } + return true; + } + + return true; + } + upi++; + } + + + return false; + } + + /** + * name : 规则6 + * desc : 连续 m 点中 有 n 点 落在中心线同一侧,C区以外。( 默认 m:5 , n:4 ) + * 注意: 如果存在满足rule5的点,会在原数组 Point.unsatisfiedRules 里标注出来。 + * return : + * 存在满足rule6的点 => true + * 不存在满足rule6的点 => false + * */ + private static Boolean rule6(List data,ControlLimit controlLimit, Integer m, Integer n){ + Integer upi = 0; + List upforMarkKey = new ArrayList<>(); + List downforMarkKey = new ArrayList<>(); +// Double[] dataArray = (Double[])data.toArray(); + Object[] dataArray = data.toArray(); + ControlLimitDetail controlLimitDetail = new ControlLimitDetail(controlLimit.getUCL(), controlLimit.getCL(), controlLimit.getLCL()); + System.out.println("controlLimitDetail : "+controlLimitDetail.toString()); + Boolean lastFlag = false; + while(upi < data.size()){ + Point[] keyList = new Point[m]; + if(m>=(data.size()-upi)){ + if(lastFlag){ + break; + } + //System.arraycopy(dataArray , 10 , keyList , 0 , 2 ); + System.arraycopy(dataArray,upi,keyList,0,(data.size()-upi)); + lastFlag = true; + }else { + System.arraycopy(dataArray,upi,keyList,0,m); + } + + Integer upTimes = 0; + Integer downTimes = 0; + for(Point i:keyList){ + if(i.getValue()>controlLimitDetail.getUC()[1]){ + upTimes++; + upforMarkKey.add(i); + System.out.println(); + } + if(i.getValue()=n || downTimes>=n){ + if(upTimes>=n){ + for(Point i:upforMarkKey){ + i.getUnsatisfiedRules().add(rule6Number); + } + return true; + } + if(downTimes>=n){ + for(Point i:downforMarkKey){ + i.getUnsatisfiedRules().add(rule6Number); + } + return true; + } + + return true; + } + upi++; + } + + + return false; + } + + /** + * name : 规则7 + * desc : 连续 n 点 落在中心线两侧的C区内。( 默认 n:15 ) + * 注意: 如果存在满足rule5的点,会在原数组 Point.unsatisfiedRules 里标注出来。 + * return : + * 存在满足rule7的点 => true + * 不存在满足rule7的点 => false + * */ + private static Boolean rule7(List data,ControlLimit controlLimit, Integer n){ + + + Integer upi = 0; + ControlLimitDetail controlLimitDetail = new ControlLimitDetail(controlLimit.getUCL(), controlLimit.getCL(), controlLimit.getLCL()); + System.out.println(controlLimitDetail.toString()); + Integer times = 0; + List markKey = new ArrayList<>(); + + + for(int i=0;icontrolLimitDetail.getLC()[0] && point.getValue()(); + } + break; + } + + //通常情况 + Point point = data.get(i); + if( isBetween( data.get(upi),data.get(upi+1) ) ){ + if(point.getValue()>controlLimitDetail.getLC()[0] && point.getValue()(); + } + }else { + times = 0; + markKey = new ArrayList<>(); + } + } + return false; + } diff --git a/ym-quality-planning/src/main/java/com/cnbm/qualityPlanning/entity/ControlLimitDetail.java b/ym-quality-planning/src/main/java/com/cnbm/qualityPlanning/entity/ControlLimitDetail.java new file mode 100644 index 0000000..2d06b89 --- /dev/null +++ b/ym-quality-planning/src/main/java/com/cnbm/qualityPlanning/entity/ControlLimitDetail.java @@ -0,0 +1,45 @@ +package com.cnbm.qualityPlanning.entity; + +import lombok.Data; + +/** + * @Desc: "" + * @Author: caixiang + * @DATE: 2022/7/12 15:17 + */ +@Data +public class ControlLimitDetail { + //控制上限 + private Double UCL; + private Double[] UA = new Double[2]; + private Double[] UB = new Double[2]; + private Double[] UC = new Double[2]; + //控制中心线 + private Double CL; + //控制下限 + private Double LCL; + private Double[] LA = new Double[2]; + private Double[] LB = new Double[2]; + private Double[] LC = new Double[2]; + + public ControlLimitDetail(Double UCL, Double CL, Double LCL){ + this.UCL = UCL; + this.CL = CL; + this.LCL = LCL; + Double agv1 = (this.UCL-this.CL)/3; + this.UC[0] = this.CL; + this.UC[1] = this.CL+agv1; + this.UB[0] = this.UC[0]; + this.UB[1] = this.UC[0]+agv1; + this.UA[0] = this.UB[0]; + this.UA[1] = this.UB[0]+agv1; + + Double agv2 = (this.CL-this.LCL)/3; + this.LC[0] = this.CL-agv2; + this.LC[1] = this.CL; + this.LB[0] = this.LC[0]-agv2; + this.LB[1] = this.LC[0]; + this.LA[0] = this.LB[0]-agv2; + this.LA[1] = this.LB[0]; + } +}