首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >计算运行平均值时出现逻辑错误

计算运行平均值时出现逻辑错误
EN

Stack Overflow用户
提问于 2011-10-28 11:01:39
回答 3查看 454关注 0票数 0

我正在尝试在SharedPreference中保持一个运行平均值。下面是我的代码:

代码语言:javascript
运行
复制
//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次运行:

代码语言:javascript
运行
复制
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

到第三次运行时,我应该已经:

代码语言:javascript
运行
复制
Running Average: 295
Average Blast Score: 98.3

我不太确定我做错了什么。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-28 11:08:51

看这一行:

代码语言:javascript
运行
复制
int averageBlastScore = (runningAverage + result.getBlastScore())/numberOfCaptures;

比方说,在第100次迭代之后,你希望发生什么?

您应该通过将分数相加并除以捕获的数量来计算平均值:

代码语言:javascript
运行
复制
int sumBlastScore = prefs.getInt(CaptureActivity.SUM_BLAST_SCORE, 0) + result.getBlastScore();
int averageBlastScore = sumBlastScore/numberOfCaptures;

System.out.println("Running Average: " + averageBlastScore);
票数 1
EN

Stack Overflow用户

发布于 2011-10-28 11:18:50

我注意到你的代码中有一个潜在的缺陷--下面这行是罪魁祸首:

代码语言:javascript
运行
复制
int averageBlastScore = (runningAverage + result.getBlastScore())/numberOfCaptures;

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

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

fine

  • (98.5+90)/3 (
  • (99+0)/1= 99 )- this is fine
  • (99+98)/2 = 98.5 - this is fine
  • (98.5+90)/3= 62.83 -this is fine
  • (99+98)/2=98.5-this is the problem

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

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

票数 0
EN

Stack Overflow用户

发布于 2011-10-28 11:42:09

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

样本: 96,99,100

总数: 96,样本:1 =>平均值= 96/1 = 96

总数: 195,样本:2 =>平均值= 195/2 = 97.5

总数: 295,样本:3 =>平均值= 295/3 = 98.333

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

我会将您的代码更改为如下所示

代码语言:javascript
运行
复制
            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();

如果您坚持存储运行平均值而不是运行总数,则必须在递增样本之前将该平均值乘以样本,以获得先前的总数,然后从那里继续。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7924684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档