逻辑错误计算运行平均值

时间:2011-10-28 03:01:39

标签: java android math sharedpreferences average

我试图在SharedPreference中保持运行平均值。这是我的代码:

//Get the number of captures
int numberOfCaptures = prefs.getInt(CaptureActivity.NUMBER_OF_CAPTURES, 0);
numberOfCaptures++;

//Calculate the average of all of the captures
int runningAverage = prefs.getInt(CaptureActivity.AVERAGE_BLAST_SCORE, 0);
System.out.println("Running Average: " + runningAverage);

int averageBlastScore = (runningAverage + result.getBlastScore())/numberOfCaptures;

System.out.println("Blast Score: "  + result.getBlastScore());
System.out.println("Number of Captures: " + numberOfCaptures);
System.out.println("Average Blast Score: " + averageBlastScore);

//Save it, so we can get it again if the user captures another swing
prefs.edit().putInt(CaptureActivity.AVERAGE_BLAST_SCORE, averageBlastScore).commit();
prefs.edit().putInt(CaptureActivity.NUMBER_OF_CAPTURES, numberOfCaptures).commit();

似乎我的跑动平均值没有得到正确的补充。

这是3次运行:

10-28 02:53:13.690: I/System.out(1162): Running Average: 0
10-28 02:53:13.690: I/System.out(1162): Blast Score: 96
10-28 02:53:13.690: I/System.out(1162): Number of Captures: 1
10-28 02:53:13.690: I/System.out(1162): Average Blast Score: 96

10-28 02:53:25.550: I/System.out(1162): Running Average: 96
10-28 02:53:25.550: I/System.out(1162): Blast Score: 99
10-28 02:53:25.550: I/System.out(1162): Number of Captures: 2
10-28 02:53:25.550: I/System.out(1162): Average Blast Score: 97

10-28 02:54:04.720: I/System.out(1162): Running Average: 97
10-28 02:54:04.720: I/System.out(1162): Blast Score: 100
10-28 02:54:04.720: I/System.out(1162): Number of Captures: 3
10-28 02:54:04.720: I/System.out(1162): Average Blast Score: 65

到第三轮我应该:

Running Average: 295
Average Blast Score: 98.3

我不确定我做错了什么。

3 个答案:

答案 0 :(得分:1)

看看这一行:

int averageBlastScore = (runningAverage + result.getBlastScore())/numberOfCaptures;

在第100次迭代之后,您期望发生什么?

您应该通过将分数相加并除以捕获次数来找到平均值:

int sumBlastScore = prefs.getInt(CaptureActivity.SUM_BLAST_SCORE, 0) + result.getBlastScore();
int averageBlastScore = sumBlastScore/numberOfCaptures;

System.out.println("Running Average: " + averageBlastScore);

答案 1 :(得分:0)

我注意到你的代码中存在潜在的缺陷 - 以下行是罪魁祸首:

int averageBlastScore = (runningAverage + result.getBlastScore())/numberOfCaptures;

让我们考虑一个你有3个分数的场景:99,98,90

由于您正在进行迭代平均操作,因此结果如下所示:

  • (99 + 0)/ 1 = 99 ----这很好
  • (99 + 98)/ 2 = 98.5 ---这很好
  • (98.5 + 90)/ 3 = 62.83 ---这是问题

相反,在第二次迭代之后,你应该每次除以2。

解决这个问题的另一种方法是等到你收到所有分数,然后将总数除以捕获次数。

答案 2 :(得分:0)

要保持运行平均值,不保持实际平均值,保持运行总数和样本数,然后计算通常方式的平均值,即总数/样本数。因此,对于这个集合,您应该在每个阶段保留这些值..

样品:96,99,100

总计:96,样品:1 => AVG = 96/1 = 96

总计:195,样品:2 => AVG = 195/2 = 97.5

总计:295,样品:3 => AVG = 295/3 = 98.333

在其他地方陈述的错误方法是在第一个样本之后总是除以2,并简单地将先前的平均值添加到新样本中。这将导致99个样本为100,而0个样本的平均值为50,这显然是错误的。

我会将您的代码更改为此类

            int numberOfCaptures = prefs.getInt(CaptureActivity.NUMBER_OF_CAPTURES, 0);
            numberOfCaptures++;

            int runningTotal = prefs.getInt(CaptureActivity.RUNNING_TOTAL, 0);
            runningTotal += result.getBlastScore();

            //Calculate the average of all of the captures
            int averageBlastScore = runningTotal / numberOfCaptures;

            System.out.println("Blast Score: "  + result.getBlastScore());
            System.out.println("Number of Captures: " + numberOfCaptures);
            System.out.println("Average Blast Score: " + averageBlastScore);

            //Save it, so we can get it again if the user captures another swing
            prefs.edit().putInt(CaptureActivity.RUNNING_TOTAL, runningTotal).commit();
            prefs.edit().putInt(CaptureActivity.NUMBER_OF_CAPTURES, numberOfCaptures).commit();

如果你坚持存储运行平均值而不是运行总数,那么在增加样本以获得之前的总数之前,你将需要通过样本得到多个平均值,然后从那里开始。