【问题标题】:And again, how to handle a huge collection in C#再一次,如何在 C# 中处理一个巨大的集合
【发布时间】:2021-12-18 06:56:01
【问题描述】:

我的“任务”的第一部分是找到一个数字(在我的例子中是 365)的所有加数 (partition) 以及这些序列的所有可能排列。

例如:对于数字 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.ForEachwhile(partition.MoveNext()) 和更改集合类型。即使partition.Count() 也需要数年才能执行。

我知道一种解决方法。计算可能会放在SplitAppends 方法中并在堆栈的顶层执行,但这种方式似乎很棘手。

【问题讨论】:

  • 我们无法优化故事,顺便说一句,我们不会阅读数论 wiki 并为您编写算法(大部分情况下)。如果您真的对答案感兴趣,您需要minimal reproducible example。但是,除非您对一组特定的优化有特别的担忧,否则您最好将其提交给 CodeReview。再一次,您需要minimal reproducible example
  • 其次,您需要确信您的实际算法是最有效的解决方案。也许你可以试试 MathOverflow
  • @TheGeneral 我的朋友。特别是对你 dotnetfiddle.net/ukdcYF 。这是我帖子中的代码(没有额外的行)。长话短说 - 阅读标题。您无需了解/阅读数学即可回答该问题。是的,我绝对确定这(图灵机)是解决我的整个问题的唯一方法。我可以解释为创造者,但没有必要。
  • 对于那些想尝试实际问题的人。您有周期化合物的 APY 公式。现在建议您可以随时(每秒)进行复合,但每种复合的价格都是固定的。您知道您的 TVL 值、每日利润 (%) 和费用价格。计算几年的最佳复合方案。

标签: c# .net performance optimization collections


【解决方案1】:

所以我发现了问题。在调用该方法时,'yield' 没有给我任何结果。只有当我使用屈服元素时。这就是为什么这个方法在 1 毫秒内完成并且“foreach”需要这么长时间。而且这个问题有~O(2^N)的难度,这就是为什么我们不能使用if for N=360。

【讨论】:

    猜你喜欢
    • 2011-09-20
    • 2021-03-03
    • 2018-08-20
    • 2021-04-06
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    相关资源
    最近更新 更多