基于ADC(Availability, Dependability, Capability)方法的系统效能评估是一种广泛应用于军事和工程领域的评估手段。这种方法通过三个核心指标——可用性(A)、可信性(D)、能力(C)——来量化一个系统在特定任务中的效能。
具体来说:
可用性(A):衡量系统在任务开始时的可用程度,反映了系统的准备状态。
可信性(D):在已知系统开始执行任务时的状态后,评估系统在使用过程中或执行任务过程中正常工作或完成规定功能的程度。
能力(C):在系统处于可用且可信的状态下,评估系统达到任务目标的能力。
ADC方法的计算公式为
E=ADC
其中 E 代表系统效能,即系统满足特定任务要求的程度。
参考文献:
《基于ADC方法的复杂武器系统效能评估方法_王晅》
《基于ADC模型优化的海上无人机作战效能评估_常会振》
以下代码基于以上两篇期刊,实现了ADC系统效能的计算。
该实现的假设是在某网络结构下,每个节点都可能存在故障的情况
并假设工作状态表如下:
1.所有节点正常运行
2.节点1故障,其他节点正常运行
3.节点2故障,其他节点正常运行
…依次类推
n.所有节点故障,系统无法正常运行
如果你的节点连接结构有所不同(比如是串联或并联系统),可根据项目实际要评估的系统效能,建设对应的工作状态表,确定计算方法,微调代码即可实现对应功能。
package com.mx.business.utils;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.RealMatrix;
import java.util.Arrays;
public class ADCUtil {
// 数组返回的第一个元素不考虑人为因素和战场环境因素;第二个元素考虑因素
public static double[] calcADC(double[] dataA, double[][] dataD, double[] dataC, double factorW, double factorH) {
// 数组转矩阵
RealMatrix matrixA = new Array2DRowRealMatrix(dataA); // nx1的矩阵
RealMatrix matrixD = new Array2DRowRealMatrix(dataD);
RealMatrix matrixC = new Array2DRowRealMatrix(dataC); // nx1的矩阵
RealMatrix transPoseA = matrixA.transpose(); // transpose转置 得到1xn的矩阵
// 首先计算 matrixA 和 matrixD 的乘积
RealMatrix productAD = transPoseA.multiply(matrixD);
// 然后计算 productAD 和 matrixC 的乘积
RealMatrix productADC = productAD.multiply(matrixC);
// 提取结果矩阵中(0,0)位置的元素 此时productADC一定是 1x1 矩阵
double calcADC = productADC.getEntry(0, 0);
// 最后将结果乘以 factorW 和 (1 - factorH)
double calcADCMH = calcADC * factorW * (1 - factorH);
double[] result = new double[2];
result[0] = Math.round(calcADC * 10000) / 10000.0; // 保留4位小数
result[1] = Math.round(calcADCMH * 10000) / 10000.0; // 保留4位小数
return result;
}
public static double[] calcDataA(double[] mtbf, double[] mttr) {
double[] dataA = new double[mtbf.length + 2];
double[] ai = new double[mtbf.length];
for (int i = 0; i < mtbf.length; i++) {
ai[i] = mtbf[i]/(mttr[i] + mtbf[i]);
}
System.out.println("Ai : --------------");
System.out.println(Arrays.toString(ai));
// A0
double first = 1;
for (int i = 0; i < mtbf.length; i++) {
first *= ai[i];
}
dataA[0] = first;
// 计算Ai 装备数量
for (int i = 1; i < mtbf.length + 1; i++) { // dataA
double temp = 1;
for (int j = 0; j < mtbf.length; j++) { // ai
if (i - 1 == j) {
temp *= 1 - ai[j];
continue;
}
temp *= ai[j];
}
dataA[i] = temp;
}
// A最后
double end = 0;
for (int i = 0; i < mtbf.length + 2; i++) {
end += dataA[i];
}
dataA[mtbf.length + 1] = 1 - end;
return dataA;
}
// 上三角矩阵,且上三角中除了三角形的边有数据,中间都没有数据;仅计算第一行,最后一列,以及对角线
public static double[][] calcDataD(double[] mtbf, double[] ti) {
double[][] dataD = new double[mtbf.length + 2][mtbf.length + 2];
// 填充整个二维数组为0
for (double[] row : dataD) {
Arrays.fill(row, 0);
}
double[] ri = new double[mtbf.length];
for (int i = 0; i < mtbf.length; i++) {
ri[i] = Math.exp(-ti[i]/mtbf[i]);
}
System.out.println("Ri : --------------");
System.out.println(Arrays.toString(ri));
// 第一行,掐头去尾
for (int i = 1; i < dataD.length - 1; i++) {
double temp = 1;
for (int j = 0; j < mtbf.length; j++) {
if (i - 1 == j) {
temp *= 1 - ri[j];
continue;
}
temp *= ri[j];
}
dataD[0][i] = temp;
}
// 对角线
for (int i = 0; i < dataD.length - 1; i++) {
double temp = 1;
for (int j = 0; j < mtbf.length; j++) {
if (i == 0) { // dataD第一个元素单独处理
temp *= ri[j];
} else {
if (i - 1 == j) {
continue;
}
temp *= ri[j];
}
}
dataD[i][i] = temp;
}
// 最后一列
for (int i = 0; i < dataD.length - 1; i++) {
double rowSum = 0;
for (int j = 0; j < dataD.length - 1; j++) {
rowSum += dataD[i][j];
}
dataD[i][dataD.length - 1] = 1 - rowSum;
}
// 最后一个元素为1
dataD[dataD.length - 1][dataD.length - 1] = 1;
return dataD;
}
// value的每一行对应指标的一条数据,即对应论文中表7的无量纲数值的一列
public static double[] calcDataC(double[] secondWeight, int[] layerNum, double[] thirdWeight, double[][] value) {
double[] dataC = new double[value.length + 1];
for (int i = 0; i < value.length; i++) {
dataC[i] = calcValueByWeight(secondWeight, layerNum, thirdWeight, value[i]);
}
// 最后一个元素为0
dataC[value.length] = 0;
return dataC;
}
// 计算人为因子W,人为因子layerNum={2,3,2},表示每个二级指标包含了多少个三级指标
public static double calcFactorW(double[] secondWeight, double[] thirdWeight, double[] value) {
int[] layerNum = {2,3,2};
return calcValueByWeight(secondWeight, layerNum, thirdWeight, value);
}
// 计算环境因子H,环境因子layerNum={3,3},表示每个二级指标包含了多少个三级指标
public static double calcFactorH(double[] secondWeight, double[] thirdWeight, double[] value) {
int[] layerNum = {3,3};
return calcValueByWeight(secondWeight, layerNum, thirdWeight, value);
}
// 权重类计算方法 layerNum 表示每个二级指标包含了多少个三级指标
private static double calcValueByWeight(double[] secondWeight, int[] layerNum, double[] thirdWeight, double[] value) {
double result = 0;
int index = 0;
for (int i = 0; i < secondWeight.length; i++) {
double thirdResult = 0;
for (int j = index; j < index + layerNum[i]; j++) {
thirdResult += thirdWeight[j] * value[j];
}
result += secondWeight[i] * thirdResult;
index+=layerNum[i];
}
return result;
}
public static void main(String[] args) {
// 论文数据示例测试
// testPaper();
// 构造zb模拟数据测试
testZb();
}
private static void testPaper() {
double[] dataA = {
0.9046, 0.0121, 0.0045,0.0024,0,0,0,0.0746
};
// calcDataA测试
// double[] mtbf = {1,2,4};
// double[] mttr = {1,8,6};
// double[] dataA1 = calcDataA(mtbf, mttr);
// System.out.println(Arrays.toString(dataA1));
double[][] dataD = {
{0.8481, 0.0229, 0.0166, 0.018, 0.0004, 0.0005, 0.0004, 0.0931},
{0, 0.871, 0, 0, 0.0171, 0.0185, 0, 0.0934},
{0, 0, 0.8652, 0, 0.0234, 0, 0.0184, 0.093},
{0, 0, 0, 0.8661, 0, 0.0234, 0.017, 0.0935},
{0, 0, 0, 0, 0.8886, 0, 0, 0.1114},
{0, 0, 0, 0, 0, 0.8895, 0, 0.1105},
{0, 0, 0, 0, 0, 0, 0.8836, 0.1164},
{0, 0, 0, 0, 0, 0, 0, 0}
};
// calcDataD测试
double[] mtbf = {1,2,3};
double[] ti = new double[]{0.1, 0.2, 0.3};
double[][] dataD1 = calcDataD(mtbf, ti);
// 装备论文的数据测试
// double[] secondWeightC = {0.4,0.3,0.2,0.1};
// int[] layerNumC= {3,4,3,4};
// double[] thirdWeightC= {0.4,0.4,0.2,0.4,0.2,0.1,0.3,0.3,0.2,0.5,0.2,0.3,0.3,0.2};
// double[][] valueC = {
// {0.8,0.8,0.9,0.8,0.9,0.8,0.9,0.8,0.9,0.8,0.8,0.8,0.9,0.7},
// {0.8,0.8,0.9,0.4,0.5,0.5,0.8,0.8,0.9,0.8,0.8,0.8,0.9,0.7}
// };
// double[] dataC = calcDataC(secondWeightC,layerNumC,thirdWeightC,valueC);
double[] dataC = {
0.7097,
0.5803,
0.7022,
0.7022,
0.5774,
0.5774,
0.6994,
0
};
// double a = (0.87 * 0.3333 + 0.91 *0.6667)*0.6483 + (0.92*0.1928+0.96*0.1062+0.96*0.7010)*0.2297 +(0.9*0.250+0.92*0.75)*0.1220;
// double factorW = 0.9117;
// double factorH = 0.1597;
double[] secondWeightW = {0.6483,0.2297,0.1220};
double[] thirdWeightW= {0.3333,0.6667,0.1928,0.1062,0.7010,0.250,0.75};
double[] valueW= {0.87,0.91,0.92,0.96,0.96,0.9,0.92};
// double b = (0.1 * 0.1428 + 0.2 *0.5715 +0.1*0.2857)*0.6667 + (0.2*0.4934+0.15*0.3108+0.1*0.1958)*0.3333;
double[] secondWeightH = {0.6667,0.3333};
double[] thirdWeightH= {0.1428,0.5715,0.2857,0.4934,0.3108,0.1958};
double[] valueH= {0.1,0.2,0.1,0.2,0.15,0.1};
double factorW = calcFactorW(secondWeightW,thirdWeightW,valueW);
double factorH = calcFactorH(secondWeightH,thirdWeightH,valueH);
double[] adc = calcADC(dataA,dataD,dataC,factorW,factorH);
System.out.println(adc[0]); //0.5899
System.out.println(adc[1]); //0.451926
System.out.println(0.5899 * 0.9117*(1-0.1597)); //0.451923
}
private static void testZb() {
double[] mtbf = {10,80,60};
// double[] mttr = {8,60,46};
double[] mttr = {1,8,6};
double[] dataA = calcDataA(mtbf, mttr);
System.out.println(Arrays.toString(dataA));
double[] ti = new double[]{1, 2, 3}; // 单位h
double[][] dataD = calcDataD(mtbf, ti);
System.out.println("--calcDataD--");
for (int i = 0; i < dataD.length; i++) {
System.out.println(Arrays.toString(dataD[i]));
}
double[] secondWeightC = {0.4,0.3,0.2,0.1};
int[] layerNumC= {3,4,3,4};
double[] thirdWeightC= {0.4,0.4,0.2,0.4,0.2,0.1,0.3,0.3,0.2,0.5,0.2,0.3,0.3,0.2};
double[][] valueC = {
{0.8,0.8,0.9,0.8,0.9,0.8,0.9,0.8,0.9,0.8,0.8,0.8,0.9,0.7},
{0.7,0.7,0.9,0.8,0.9,0.8,0.9,0.8,0.9,0.8,0.8,0.8,0.9,0.7},
{0.6,0.6,0.9,0.4,0.5,0.5,0.8,0.8,0.9,0.8,0.8,0.8,0.9,0.7},
{0.5,0.5,0.9,0.4,0.5,0.5,0.8,0.8,0.9,0.8,0.8,0.8,0.9,0.7}
};
double[] dataC = calcDataC(secondWeightC,layerNumC,thirdWeightC,valueC);
System.out.println(Arrays.toString(dataC));
double[] secondWeightW = {0.6483,0.2297,0.1220};
double[] thirdWeightW= {0.3333,0.6667,0.1928,0.1062,0.7010,0.250,0.75};
double[] valueW= {0.87,0.91,0.92,0.96,0.96,0.9,0.92};
double factorW = calcFactorW(secondWeightW,thirdWeightW,valueW);
double[] secondWeightH = {0.6667,0.3333};
double[] thirdWeightH= {0.1428,0.5715,0.2857,0.4934,0.3108,0.1958};
double[] valueH= {0.1,0.2,0.1,0.2,0.15,0.1};
double factorH = calcFactorH(secondWeightH,thirdWeightH,valueH);
double[] adc = calcADC(dataA,dataD,dataC,factorW,factorH);
System.out.println("ADC: " + adc[0]); // 0.7482
System.out.println("ADCMH: " + adc[1]); // 0.5731
}
}