c# - 在几个小时内平均分配项目数量

标签 c# math distribution

我有数量不定的项目,我想在不定的时间内分配。我遇到的问题是如何分配剩余部分,以便“悬垂”之间的空间尽可能相等。例如,如果我有 13 个项目 (X) 分布在 5 小时内,我想结束

Hours:    1    2    3    4    5
---------------------------------
          x    x    x    x    x
          x    x    x    x    x  
          x         x         x

我不确定我是不是想多了。我目前正在检查项目数量是否大于小时数。如果那是真的,我将除以(项目数/小时数)。然后我认为我必须除以(小时数/剩余时间)...但是对于上面的示例:5/3=1.6,四舍五入为 2。我认为我必须使用 Math.Floor 以某种方式,但我目前不确定如何。

对于 5 小时内的 4 项,我想以 X 结尾 对于带有 Ys 的 2 个项目 对于带有 Zs 的 1 个项目

 1    2    3    4    5
------------------------
 x    x         x    x

      y         y

           z

项目数量和小时数是可变的。

好的,我认为我目前正走在正确的轨道上。我现在正试图将垃圾箱分成两半,并将剩余的一个放在中央垃圾箱中。递归重复,直到余数为 0。

最佳答案

编辑:修复了偶数小时和项目的问题。

这是一个难题,下面是解决方案。我已经为一个完全通用的问题编写了解决方案,因此它适用于任意时间和项目数量。这是示例输出:

Items=10, Hours=14
XX XX XX XX XX

Items=11, Hours=14
XX XXXXX XX XX

Items=12, Hours=14
XX XXXXXXXX XX

Items=16, Hours=13
XXXXXXXXXXXXX
     XXX

Items=17, Hours=13
XXXXXXXXXXXXX
X    X X    X

Items=18, Hours=13
XXXXXXXXXXXXX
X    XXX    X

Items=19, Hours=13
XXXXXXXXXXXXX
X X  X X  X X

Items=20, Hours=13
XXXXXXXXXXXXX
X X  XXX  X X

Items=21, Hours=13
XXXXXXXXXXXXX
X XX X X XX X

以下是解决方案的工作原理:

  1. 填充行的数量是微不足道的,你可以通过 (items/hours) * hours 得到它。
  2. 最后一行是需要所有魔法的地方。
  3. 当剩余项目的数量为奇数时,我们要打开中心。如果小时数也是奇数,则中心定义明确,否则我们就不走运了,在这种情况下我们会出现一些“不平衡”。
  4. 对于偶数项,我们将它们配对并按平衡二叉树的顺序分配每对。这基本上意味着我们首先将每一对放在最后。然后下一对中途并递归地遵循模式。这可能是最难理解的部分,因此建议使用纸和笔:)。

代码如下:

static void Main(string[] args)
{
    var hours = 13;
    for (var items = 16; items < 22; items++)
        PrintDistribution(items, hours);
}

private static void PrintDistribution(int items, int hours)
{
    Console.WriteLine(string.Format("\nItems={0}, Hours={1}", items, hours));
    for (var i = 0; i < (items / hours) * hours; i++)
    {
        Console.Write('X');
        if ((i + 1) % hours == 0)
            Console.WriteLine();
    }

    var line = new StringBuilder(new string(' ', hours));
    var remaining = items % hours;
    var evens = remaining / 2;
    var odd = remaining - (evens * 2);
    var seq = BinaryTreeSequence(hours / 2).GetEnumerator();
    for (var i = 0; i < evens; i++)
    {
        seq.MoveNext();
        line[seq.Current] = 'X';
        line[hours - seq.Current - 1] = 'X';
    }

    if (odd > 0)
        if (hours % 2 == 0)
        {
            seq.MoveNext();
            line[seq.Current] = 'X';
        }
        else
            line[hours / 2] = 'X';

    Console.WriteLine(line);
}


public static IEnumerable<int> BinaryTreeSequence(int count)
{
    if (count > 1)
        yield return count - 1; 
    if (count > 0)
        yield return 0;

    var seqQueue = new Queue<Tuple<int, int, int>>();
    Enqueue(seqQueue, 0, count - 1);

    for (var seqIndex = count - 2; seqIndex > 0; seqIndex--)
    {
        var moreNeeded = seqQueue.Count < seqIndex;

        var seq = seqQueue.Dequeue();
        yield return seq.Item1;

        if (moreNeeded)
        {
            Enqueue(seqQueue, seq.Item1, seq.Item3);
            Enqueue(seqQueue, seq.Item2, seq.Item1);
        }
    }
}

private static void Enqueue(Queue<Tuple<int, int, int>> q, int min, int max)
{
    var midPoint = (min + max) / 2;
    if (midPoint != min && midPoint != max)
        q.Enqueue(Tuple.Create(midPoint, min, max));
}

关于c# - 在几个小时内平均分配项目数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19962065/

相关文章:

c# - ASP.Net 中的日期差异

c# - 要求基类的子级从基类调用方法的设计模式

python - python中的学生t置信区间

macos - 如何为我的App Store应用程序创建Mac非App Store发行目标?

c# - 关闭一个窗口后关闭 WPF 中的所有窗口

c# - 为什么 libphonenumber 网站返回的结果与 libphonenumber 库不同?

计算具有不同成员数的组的点总和的算法

math - Lua随机函数困惑

c# - C# 中的边缘检测

c++ - 像 discrete_distribution<float> 这样的随机分布