2017-08-01 4 views
0

私は現在、指数関数的降下(http://www.acodersjourney.com/2016/02/26-handle-transient-errors-in-c/)の実装に取り​​組んでいます。結果が限界内になるような最大電力の計算

var delay = (int) Math.Round(Math.Pow(timeBetweenAttempts, attempt), MidpointRounding.AwayFromZero); 

明らかに、この遅延も10ミリ秒であるの試行の間の時間で、非常に迅速に、非常に大規模な取得を開始:

は、私はそのようなことを、遅延が待機するように計算しています。

私は似た何かをできるようにしたいと思います:

var maxTimeBetweenAttempts = 5000; // 5 seconds is the hard limit 
var nominalTimeBetweenAttempts = 10; 

var maxNumberOfAttempts = // calculate the maximum number of raises that would hold below 5000. 

明らかにこれは、ループを使用して計算することができますが、これを行うには、よりエレガントな方法があった場合、私は不思議でしたか?

+1

理由だけではなく、 '' Math.Min(遅延、maxTimeBetweenAttempts)を使用していませんか? –

+0

'pow(x、n)'の代わりに 's * pow(x/s、n)'という遅延ファミリが必要です。許容可能な最大のnは、 '(log(maxdelay)-log(s))/(log(x)-log(s))であるlog(maxdelay/s)/ log )) ')。実際には、あなたは既にあなたの好みのユニットによって暗黙のうちに選択された倍率を持っています。 10ミリ秒と.01秒の時間は同じですが、 'pow(.01、n)'を実行した場合、遅延は「n」が増えるにつれて*短縮されます。 –

+0

@ScottChamberlain:それは "遅延が非常に速く大きくなる"という問題を解決しないためです。 –

答えて

0

累乗の逆数は対数ですので、それを使用できます。 あなたは試みが丸め後のしきい値を下回っていたかどうかを確認するには

if (attempt < Math.Log(maxTimeBetweenAttempts)/Math.Log(nominalTimeBetweenAttempts)) 
{ 
    Retry(++attempt); 
} 

を使用します。

しかし、これは余計な計算を必要とするため、指数関数的に行うよりも、(学校ではほとんどの人が見たことのない対数計算を使用しているため)あまり明白ではありません。それをテストする。

ie。

if(Math.Pow(nominalTimeBetweenAttempts, attempt) < maxTimeBetweenAttempts) 
{ 
    Retry(++attempt); 
} 

編集:

あなたの質問を再読み込み、明示的にあなたは、彼らが一定の長さに到達する前に再試行の最大数を知りたいと述べています。それは次のようになります。

var maximumNumberOfAttempts = Math.Floor(Math.Log(maxTimeBetweenAttempts)/Math.Log(nominalTimeBetweenAttempts)) 
+0

あなたの質問には答えられなかったようです。私は何が欠けていますか? – Max

関連する問題