我的“任務”的第一部分是找到一個數字(在我的例子中是 365)的所有加數(磁區)以及這些序列的所有可能排列。
例如:對于數字 3,我們有三個可能的加數序列 (3) (1;2) (1;1;1) 但我的方法給出 (3) (1;2) (2;1) (1;1;1) ),因為我需要。
IEnumerable<int[]> SplitAddends(int n) {
for (int i = 1; i < n; i ) {
var part = SplitAddends(n - i);
foreach (var array in part) {
var newArray = new int[array.Length 1];
newArray[0] = i;
Array.Copy(array, 0, newArray, 1, array.Length);
yield return newArray;
}
}
yield return new []{n};
}
這種方法在不到 1 毫秒的時間內給出結果,它是正確的。問題是這個任務的第二部分。我需要對每個元素進行一些計算。例如:
void ExampleMethod(int N) {
var partition = SplitAddends(N); // < 1ms execution time
foreach (var variant in partition) { // problematic line
var someResult = 0f;
foreach (var item in variant) {
someResult = SomeEquation(item);
}
SendToCompare(someResult);
}
}
像 15-25 這樣的數字需要幾秒鐘(對于 N=20 磁區有 524288 個序列),像 35-50 這樣的數字需要幾個小時。
我已經嘗試過諸如Parallel.ForEach,while(partition.MoveNext())和更改集合型別之類的方法。甚至partition.Count()需要數年才能執行。
我知道一種解決方法。計算可以放在SplitAppends方法內部并在堆疊的頂層執行,但這種方式似乎很棘手。
uj5u.com熱心網友回復:
所以我發現了問題。在呼叫該方法時,'yield' 沒有給我任何結果。只有當我使用屈服元素時。這就是為什么這個方法在 1 毫秒內完成,而 'foreach' 需要這么長時間。并且問題有~O(2^N) 難度,這就是為什么我們不能使用 if for N=360。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/350338.html
上一篇:我應該使用Task.Run還是Task.FromResult?
下一篇:沒有找到“eslint”目標
