创建一个预测某个处理器故障概率的函数



我的程序(在Java中)有一个名为Processor的对象,它可以经历迭代事件。

每个处理器都有以下字段:
double lambda- 衰减指数;
double failProb- 每次迭代失败的概率;
int age- 处理器处于活动状态的迭代次数;
boolean failed- 描述处理器是否"出现故障">

在每个迭代事件期间,将发生以下情况:

  1. age递增 1;
  2. failPorb根据此函数更新:failProb=1-Math.exp(-lambda*age);
  3. 一个随机数(0~1)与failProb进行比较,如果比较结果为真,则random-number < failProb--,failed的域变为true

总之,每次迭代都可能导致处理器"失败",并且失败的概率随着每次迭代而增加。

问题是,我如何在处理器中编写一个函数来预测处理器在接下来的x次迭代中失败的概率(如有必要,在得出更大的故障概率方面犯错?

尝试的解决方案:

1:

public double predictFailProb(int x){
return(1-Math.exp(-lambda*(age+x)));
}

上述方法不起作用,因为它只给出了 x 迭代时间段最后一个failProb,而不考虑处理器可能在此之前失败。换句话说,这确实预测了处理器何时处于年龄failProbx+current_age

阿拉伯数字:

public double predictFailProb(int x){
double t=1;
for(int i=0; i<x; i++){
t*=1-(1-Math.exp(-lambda*(age+i)));
}
return (1-t);
}

从理论上讲,上述值应计算处理器在接下来的x次迭代中不会失败的概率,然后返回该值的赞美。如果这是功能性的,感觉很初级和性能密集型。我有一种感觉,对于相同的函数,可能有一个更简单的表达式。

以下是x步骤中失败的显式公式。

鉴于:

  • A_k处理器在步骤k中失败的事件。
  • k-th步骤失败的概率由下式给出P[A_k] = 1 - exp(-lambda * (age + k))

我们希望计算处理器在x步内失败的概率。

它持有:

P[fails within first x steps]
= 1 - P[does not fail within x steps]
= 1 - P[AND_{k = 1}^x not(A_k)]
= 1 - prod_{k=1}^x P[not(A_k)]     // independence assumption
= 1 - prod_{k=1}^x (1 - P[A_k])
= 1 - prod_{k=1}^x (1 - 1 + exp(-lambda * (age + k)))
= 1 - prod_{k=1}^x exp(-lambda * (age + k))
= 1 - exp(-lambda * age * x - lambda * sum_{k=1}^x k)
= 1 - exp(-lambda * age * x) * exp(-lambda * x * (x + 1) / 2)

因此,在Java中,它可以在恒定时间内计算如下:

double probFailureWithin(int steps, int age, double lambda) {
return 
1.0 - 
Math.exp(-lambda * age * steps) * 
Math.exp(-lambda * steps * (steps + 1) / 2.0);
}

以下是一系列完整的实验,证实了这个显式公式是正确的:

double probFailureWithin(int steps, int age, double lambda) {
return 
1.0 - 
Math.exp(-lambda * age * steps) * 
Math.exp(-lambda * steps * (steps + 1) / 2.0);
}
boolean randFailureWithin(int steps, int age, double lambda) {
for (int k = 1; k <= steps; k++) {
double failProb = 1 - Math.exp(-lambda * (age + k));
if (Math.random() < failProb) {
return true;
}
}
return false;
}
double bruteforceFailureWithin(int steps, int age, double lambda) {
double nonFailureProb = 1.0;
for (int k = 1; k <= steps; k++) {
nonFailureProb *= Math.exp(-lambda * (age + k));
}
return 1.0 - nonFailureProb;
}
void runExperiment(int steps, int age, double lambda, int reps) {
int numFailures = 0;
for (int rep = 0; rep < reps; rep++) {
if (randFailureWithin(steps, age, lambda)) {
numFailures++;
}
}
double empiricalProb = numFailures / (double)reps;
double predictedProb = probFailureWithin(steps, age, lambda);
double bruteforceProb = bruteforceFailureWithin(steps, age, lambda);
System.out.println(
"a = " + age + 
" l = " + lambda + 
" s = " + steps +
" Empirical: " + empiricalProb + 
" Predicted: " + predictedProb + 
" BruteForce: " + bruteforceProb
);
}
void runExperiments(int reps) {
for (double lambda : new double[]{0.7, 0.5, 0.1, 0.01, 0.0001}) {
for (int age : new int[]{0, 1, 10, 1000, 10000}) {
for (int steps : new int[]{0, 1, 10, 1000, 10000}) {
runExperiment(steps, age, lambda, reps);
}
}
}
}

只需runExperiments(10000)或类似的东西,并比较以下值:

  • 重复实验得到的经验随机值
  • 显式公式
  • 带循环的暴力破解公式

您将看到显式公式与暴力乘法方法完全相同,并且这两个公式都非常接近经验结果。

摘录:

a = 500 l = 1.0E-4 s = 1 
Empirical:  0.049054 
Predicted:  0.04886569368574745 
BruteForce: 0.04886569368574745
a = 500 l = 1.0E-4 s = 10 
Empirical:  0.396329 
Predicted:  0.39679610193504744 
BruteForce: 0.39679610193504766
a = 500 l = 1.0E-4 s = 100 
Empirical:  0.995945 
Predicted:  0.9959336114191201 
BruteForce: 0.9959336114191201

最新更新