新增判读方案

This commit is contained in:
caixiang 2022-07-15 17:15:42 +08:00
parent 970359823b
commit 13020d05c9
2 changed files with 371 additions and 31 deletions

View File

@ -1,13 +1,12 @@
package com.cnbm.qualityPlanning.common; package com.cnbm.qualityPlanning.common;
import com.cnbm.qualityPlanning.entity.ControlLimit; import com.cnbm.qualityPlanning.entity.ControlLimit;
import com.cnbm.qualityPlanning.entity.ControlLimitDetail;
import com.cnbm.qualityPlanning.entity.Point; import com.cnbm.qualityPlanning.entity.Point;
import io.swagger.models.auth.In; import io.swagger.models.auth.In;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/** /**
* @Desc: "检测参数统计受控 检验类" * @Desc: "检测参数统计受控 检验类"
@ -27,18 +26,18 @@ public class StatisticalControlledTest {
private static final Integer rule10Number = 10; private static final Integer rule10Number = 10;
public static List<Point> createData(){ public static List<Point> createData(){
Point point = new Point(1,new Double(1)); Point point = new Point(1,new Double(1.7));
Point point2 = new Point(2,new Double(2)); Point point2 = new Point(2,new Double(8));
Point point3 = new Point(3,new Double(3)); Point point3 = new Point(3,new Double(8));
Point point4 = new Point(4,new Double(4)); Point point4 = new Point(4,new Double(1.7));
Point point5 = new Point(5,new Double(5)); Point point5 = new Point(5,new Double(1.7));
Point point6 = new Point(6,new Double(6)); Point point6 = new Point(6,new Double(1.7)); //3
Point point7 = new Point(7,new Double(7)); Point point7 = new Point(7,new Double(1.7)); //3
Point point8 = new Point(8,new Double(8)); Point point8 = new Point(8,new Double(1.7)); //3 //3
Point point9 = new Point(9,new Double(9)); Point point9 = new Point(9,new Double(1.7));
Point point10 = new Point(10,new Double(10)); Point point10 = new Point(10,new Double(1.7));
Point point11 = new Point(11,new Double(11)); Point point11 = new Point(11,new Double(1.7));
Point point12 = new Point(12,new Double(12)); Point point12 = new Point(12,new Double(1.7));
List<Point> list = new ArrayList<>(); List<Point> list = new ArrayList<>();
list.add(point); list.add(point);
list.add(point2); list.add(point2);
@ -58,33 +57,60 @@ public class StatisticalControlledTest {
public static void main(String[] args) { public static void main(String[] args) {
List<Point> list = createData(); List<Point> list = createData();
ControlLimit controlLimit = new ControlLimit(new Double(12),new Double(2),new Double(1)); ControlLimit controlLimit = new ControlLimit(new Double(12),new Double(2),new Double(1));
//
//TEST FOR RULE1 // //TEST FOR RULE1
Boolean aBoolean1 = rule1(list, controlLimit); // Boolean aBoolean1 = rule1(list, controlLimit);
//
//TEST FOR RULE2 //TEST FOR RULE2
Boolean aBoolean2 = rule2(list, controlLimit, 9); Boolean aBoolean2 = rule2(list, controlLimit, 9);
System.out.println(); System.out.println();
//
//
// //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 RULE3 // //TEST FOR RULE6
Boolean aBoolean3 = rule3(list, 3); // 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(); 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 * name : 规则1
* desc : 控制图上有 1 个点位于三倍标准差以外(对中心线来说)母体的 $\sigma$ * desc : 控制图上有 1 个点位于三倍标准差以外(对中心线来说)母体的 $\sigma$
* * 注意 如果存在满足rule1的点会在原数组 Point.unsatisfiedRules 里标注出来
* return : 返回的 就是不满足 规则1 的点 * return :
* 存在满足rule1的点 => true
* 不存在满足rule1的点 => false
* */ * */
private static Boolean rule1(List<Point> data, ControlLimit controlLimit){ private static Boolean rule1(List<Point> data, ControlLimit controlLimit){
Boolean flag = false;
for(Point i:data){ for(Point i:data){
if(i.getValue() > controlLimit.getUCL() || i.getValue() < controlLimit.getLCL()){ 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<Point> data,List<Integer> keys,Integer ruleNumber){ private static void markUnsatisfiedRulesByKeys(List<Point> data,List<Integer> keys,Integer ruleNumber){
@ -96,8 +122,11 @@ public class StatisticalControlledTest {
/** /**
* name : 规则2 * name : 规则2
* desc : 连续 n 点落在中心线的用一侧 (默认9) * desc : 连续 n 点落在中心线的用一侧 (默认9)
* * 注意 如果存在满足rule2的点会在原数组 Point.unsatisfiedRules 里标注出来
* return : 返回的 就是不满足 规则2 的点 * //todo 存在bug while((upi+1) < data.size()){ 最后一个点轮询不到
* return :
* 存在满足rule2的点 => true
* 不存在满足rule2的点 => false
* */ * */
private static Boolean rule2(List<Point> data, ControlLimit controlLimit,Integer n){ private static Boolean rule2(List<Point> data, ControlLimit controlLimit,Integer n){
List<Point> upList = new ArrayList<>(); List<Point> upList = new ArrayList<>();
@ -113,13 +142,19 @@ public class StatisticalControlledTest {
//上侧的情况 //上侧的情况
Integer upi = 0; Integer upi = 0;
Integer uptime = 0; Integer uptime = 0;
Integer upTotalSize = upList.size();
//标注不合格的 参数 //标注不合格的 参数
List<Point> forMarkPoints = new ArrayList<>(); List<Point> forMarkPoints = new ArrayList<>();
while((upi+1) < upList.size()){ while((upi+1) < upList.size()){
//if((upList.get(upi).getPosition()+1)==upList.get(upi+1).getPosition()){ //if((upList.get(upi).getPosition()+1)==upList.get(upi+1).getPosition()){
if(isBetween(upList.get(upi),upList.get(upi+1))){ if(isBetween(upList.get(upi),upList.get(upi+1))){
uptime +=1; uptime +=1;
forMarkPoints.add(upList.get(upi)); forMarkPoints.add(upList.get(upi));
if((upi+1)==upTotalSize){
uptime +=1;
forMarkPoints.add(upList.get(upi+1));
}
//只要到达n 就return防止中间段到达 后面又被重置了 //只要到达n 就return防止中间段到达 后面又被重置了
if(uptime>=n){ if(uptime>=n){
//1. //1.
@ -138,6 +173,7 @@ public class StatisticalControlledTest {
} }
}else { }else {
forMarkPoints = new ArrayList<>(); forMarkPoints = new ArrayList<>();
upTotalSize-=1;
uptime = 0; uptime = 0;
} }
upi++; upi++;
@ -147,11 +183,16 @@ public class StatisticalControlledTest {
//下侧的情况 //下侧的情况
Integer downi = 0; Integer downi = 0;
Integer downtime = 0; Integer downtime = 0;
Integer totalSize = downList.size();
forMarkPoints = new ArrayList<>(); forMarkPoints = new ArrayList<>();
while((downi+1) < downList.size()){ 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; downtime +=1;
forMarkPoints.add(downList.get(downi)); forMarkPoints.add(downList.get(downi));
if((downi+1)==totalSize){
downtime++;
forMarkPoints.add(downList.get(downi+1));
}
if(downtime>=n){ if(downtime>=n){
for (Point key:forMarkPoints){ for (Point key:forMarkPoints){
@ -166,6 +207,7 @@ public class StatisticalControlledTest {
return true; return true;
} }
}else { }else {
totalSize-=1;
forMarkPoints = new ArrayList<>(); forMarkPoints = new ArrayList<>();
downtime = 0; downtime = 0;
} }
@ -179,8 +221,10 @@ public class StatisticalControlledTest {
/** /**
* name : 规则3 * name : 规则3
* desc : 连续 n 点递增或者递减 (默认6) * desc : 连续 n 点递增或者递减 (默认6)
* * 注意 如果存在满足rule3的点会在原数组 Point.unsatisfiedRules 里标注出来
* return : 返回的 就是不满足 规则2 的点 * return :
* 存在满足rule3的点 => true
* 不存在满足rule3的点 => false
* */ * */
private static Boolean rule3(List<Point> data, Integer n){ private static Boolean rule3(List<Point> data, Integer n){
@ -232,6 +276,257 @@ public class StatisticalControlledTest {
return false; 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<Point> data, Integer n){
Integer upi = 0;
Boolean current;
Boolean nextNeeded;
Integer times = 0;
List<Integer> 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<Point> data,ControlLimit controlLimit, Integer m, Integer n){
Integer upi = 0;
List<Point> upforMarkKey = new ArrayList<>();
List<Point> 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()<controlLimitDetail.getLB()[0]){
downTimes++;
downforMarkKey.add(i);
}
}
if(upTimes>=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<Point> data,ControlLimit controlLimit, Integer m, Integer n){
Integer upi = 0;
List<Point> upforMarkKey = new ArrayList<>();
List<Point> 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()<controlLimitDetail.getLC()[0]){
downTimes++;
downforMarkKey.add(i);
}
}
if(upTimes>=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<Point> 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<Point> markKey = new ArrayList<>();
for(int i=0;i<data.size();i++){
//判断最后一次
if((upi+1) == data.size()){
Point point = data.get(upi);
if(point.getValue()>controlLimitDetail.getLC()[0] && point.getValue()<controlLimitDetail.getUC()[1]){
times++;
markKey.add(point);
if(times==n){
for(Point j:markKey){
j.getUnsatisfiedRules().add(rule7Number);
}
return true;
}
}else {
times = 0;
markKey = new ArrayList<>();
}
break;
}
//通常情况
Point point = data.get(i);
if( isBetween( data.get(upi),data.get(upi+1) ) ){
if(point.getValue()>controlLimitDetail.getLC()[0] && point.getValue()<controlLimitDetail.getUC()[1]){
times++;
markKey.add(point);
if(times==n){
for(Point j:markKey){
j.getUnsatisfiedRules().add(rule7Number);
}
return true;
}
}else {
times = 0;
markKey = new ArrayList<>();
}
}else {
times = 0;
markKey = new ArrayList<>();
}
}
return false;
}

View File

@ -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];
}
}