3

たとえば、最終的な数字の配列がある場合は、次のように言います。

{1, 5, 7, 2}

それらの平均は次のようになります。

(1 + 5 + 7 + 2) / 4;   //Or, sum of all elements, divided by their number

しかし、私の配列が絶えず成長していて、完全な配列がまだ知られていないインスタンスで現在の平均数を知る必要がある場合はどうでしょうか。それはどうやって計算するのですか?

たとえば、現在のデータ転送速度を表示しようとしているときなどです。

4

8 に答える 8

3

新しい値を取得するたびに合計とカウントを更新し、ユーザーに表示する必要がある場合は単純に 2 つを割ります。

ただし、データ転送速度の場合、これは問題のあるアプローチです。高帯域幅で転送を開始した後、接続が切断されたシナリオを考えてみてください。単純な平均では、現在の転送速度が 0 であることを UI が反映するまでに長い時間がかかる可能性があります。加重移動平均を使用すると簡単な方法ですUI をより応答性の高いものにします。

これの最も簡単な実装は、転送レートを定期的に (たとえば 5 秒ごとに) サンプリングし、次のような方法でレートを計算することです。

 float weight = 2.0; //you are going to want to tweak this to get the right balance between "responsive" and "noisy"

 void UpdateAverage(float newValue)
 {
    this.Average = (this.Average + (newValue*weight))/(weight+1)
 }
于 2013-05-23T22:11:04.907 に答える
3

running total一定のスペースの複雑さ (1) を持つ (累積) を持つための単純なアプローチを使用します。そして avg の要求に応じて、 である結果を返し running total/total number of itemます。累積合計を見つけるために後で配列を反復処理しないため、複雑な時間の延長はありません。

于 2013-05-23T22:21:50.523 に答える
2

ここでのパーティーに遅れたことは承知していますが、2000 年にアダプティブ ロード バランサーを作成していたときに、これと同様の問題を解決しました。標準平均には 2 つの問題があり、どちらも回答に記載されています。

  1. オーバーフローのシナリオ
  2. - 現在の合計を保持すると、オーバーフローが発生します
  3. 平均の再計算
  4. - 通常、サンプルごとにこれを行う必要があります

したがって、通常の平均計算を、数学者が「再帰関係」と呼ぶものに変えることができます。これは、以前の平均を保存し、それを使用して新しい平均を計算することを意味します (ヤウルの答えに似ています。反対票が投じられたことはわかりません)。私は当時 Delphi でオリジナルを書いていたので、ごく最近、同じことを .NET で再度行い、アイテムのリストが大きくなるにつれて連続平均を計算する標準プロセスと比較しました。

自己宣伝したくなくても (タイピングの指を節約するためにリンクを投稿しています)、理論的な処理、代数、比較実験の結果、および問題への対処方法については、次の URL を参照してください。

http://goadingtheitgeek.blogspot.co.uk/2014/05/blast-from-past.html

お役に立てば幸いです。

于 2014-05-25T20:46:15.900 に答える
1

あなたは移動平均を探しています:

    static void Main(string[] args) {
        var nums = Enumerable.Range(1, 5).Select(n => (double)n);
        nums = nums.Concat(nums.Reverse());

        var sma3 = SMA(3);
        var sma5 = SMA(5);

        foreach (var n in nums) {
            Console.WriteLine("{0}    (sma3) {1,-16} (sma5) {2,-16}", n, sma3(n), sma5(n));
        }
    }

    static Func<double, double> SMA(int p) {
        Queue<double> s = new Queue<double>(p);
        return (x) => {
            if (s.Count >= p) {
                s.Dequeue();
            }
            s.Enqueue(x);
            return s.Average();
        };
    }

ソース: http://rosettacode.org/wiki/Averages/Simple_moving_average#C.23

于 2013-05-23T22:12:36.553 に答える
-3
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int  n = 3 , x , sum = 0 ;
            double ave;

            for (int i = 0; i < n; i++ )
            {
                Console.WriteLine("enter the number:");
                x = Convert.ToInt16(Console.ReadLine());
                sum += x;
            }

            ave = (double)(sum) / 3;
            Console.WriteLine("average:");
            Console.WriteLine( ave );
            Console.ReadLine();
        }
    }
}
于 2016-11-16T12:02:56.953 に答える