c# - 如何加速计算多个项目的所有可能分布的算法?

标签 c# algorithm recursion

我想计算一些项目的所有可能(使用特定步骤)分布。总和必须加起来为 1。 我的第一种方法如下:

var percentages = new List<double>(new double[3]);

while (Math.Abs(percentages.Last() - 1.0) > 0.01) 
{
    Increment(percentages, 0);
    if (Math.Abs(percentages.Sum() - 1.0) < 0.01)
    {
        percentages.ForEach(x => Console.Write("{0}\t", x));
        Console.WriteLine();
    }
}

private void Increment(List<double> list, int i)
{
    if (list.Count > i)
    {
        list[i] += 0.1;
        if (list[i] >= 1)
        {
            list[i] = 0;
            Increment(list, ++i);
        }
    }
}

输出想要的结果:

1 0 0
0.9 0.1 0
0.8 0.2 0
0.7 0.3 0
0.6 0.4 0
0.5 0.5 0
0.4 0.6 0
0.3 0.7 0
0.2 0.8 0
0.1 0.9 0
0 1 0
0.9 0 0.1 ..

我想知道如何加快计算速度,因为项目的数量可能会变得非常大 (>20)。 显然我计算了很多分布只是为了把它们扔掉,因为它们加起来不等于 1。 有什么想法吗?

最佳答案

这适用于 3 组数字:

var query =
    from x in Enumerable.Range(0, 11)
    from y in Enumerable.Range(0, 11 - x)
    let z = 10 - x - y
    select new [] { x / 10.0, y / 10.0, z / 10.0 };

var percentages = query.ToList();

percentages
    .ForEach(ps => Console.WriteLine(String.Join("\t", ps)));

这是一个通用版本:

Func<int, int[], int[][]> generate = null;
generate = (n, ns) =>
    n == 1
        ? new int[][]
            {
                ns
                    .Concat(new [] { 10 - ns.Sum() })
                    .ToArray()
            }
        : Enumerable
            .Range(0, 11 - ns.Sum())
            .Select(x =>
                ns.Concat(new [] { x }).ToArray())
            .SelectMany(xs => generate(n - 1, xs))
            .ToArray();

var elements = 4;

var percentages =
    generate(elements, new int[] { })
        .Select(xs => xs.Select(x => x / 10.0).ToArray())
        .ToList();

只需更改 elements 值即可获取内部数组的元素数。

关于c# - 如何加速计算多个项目的所有可能分布的算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26641342/

相关文章:

c# - 当文件的内容也带有希伯来字母时,如何使用 openFileDialog 打开文本文件?

c# - 删除 Windows 窗体中的标题栏

c# - 使用 JsonConvert.DeserializeObject 将 Json 反序列化为 C# POCO 类

c++ - 用于在图中查找约束最短路径的高效数据结构

python - 剪刀石头布机器人算法

php - 这是 PHP 递归的废话吗?

c# - Directory.getfile 和 Windows Phone 7

c++ - 递归创建——nested()

recursion - Common-Lisp 中的递归阶乘函数

java - 递归问题 - 这个解决方案是否正确,是否有更简单的解决方案?