2011-10-28 55 views
0

我試圖在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 

我不太確定我在做什麼錯。

+0

從數學角度來說,你的意思是平均跑步數?如果你想要一個移動平均線,那麼你需要保留最後的'N'個數據點,以便將它們相加並將它們除以N.如果你想要一個指數移動平均線,你可以做你現在正在做的事情,由'k'表示衰減因子。 – ObscureRobot

+0

我只想取平均值。我想我可能會使用錯誤的術語。隨着我的應用程序繼續運行,我想要獲取我的數據點的平均值。 –

+0

然後,您將需要保留最後的N個值,而不僅僅是以前的平均值。 – ObscureRobot

回答

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); 
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。

解決此問題的另一種方法是等待,直到您收到所有分數,然後將總數除以捕獲次數。

0

爲了保持運行平均值,您不保留實際平均值,保留運行總數和樣本數量,然後按通常方式計算平均值,即總數/樣本。因此,對於這組你應該在每個階段保持這些值..

樣品:96,99,100

總計:96,樣品:1 => AVG = 96/1 = 96

總計:195,樣品:2 => AVG =二分之一百九十五= 97.5

總計:295,樣品:3 => AVG =三分之二百九十五= 98.333

別處所述錯誤的方式是總是通過劃分兩個在第一個樣本之後,並且簡單地將以前的平均值添加到新的樣本。這將導致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(); 

,你將不得不多次通過樣本平均之前增加採樣,以獲得先前的總數,然後從那裏繼續。