计算该项目旁边的百分比分配百分比、该项目、分配

2023-09-11 23:01:02 作者:浪不出來的漫

我的工作,涉及转接电话到多个目标的项目。

I'm working on a project that involves diverting phone calls to a number of destinations.

例如,我想:

呼叫 10%,去到目的地A 呼叫 20%,去到目的地乙 呼叫 30%,去到目的地ç 呼叫 40%,去到目的地ð 10% of calls to go to destination A 20% of calls to go to destination B 30% of calls to go to destination C 40% of calls to go to destination D

目的地及比例的数目必须是可配置的。

The number of destinations and their percentages must be configurable.

我一直在思考如何做到这一点,玩弄以s preadsheets有的code,我想出了这一点:

I've been thinking about how to do this, playing around with spreadsheets and some code, and I came up with this:

对于每个目标,采取随机数,按比例乘以它,并选择具有最高数量的目的。像这样的:

For each destination, take a random number, multiply it by the percentage, and select the destination with the highest number. Like this:

Item: RANDOM * PERCENTAGE = RESULT
   A:   48   *     10     =   480
   B:   33   *     20     =   660
   C:   81   *     30     =  2430  <--- Highest number, select C
   D:    5   *     40     =   200

我想我的工作了为D显然是选择了最,其次是C,那么B,并至少所有A。

I thought I'd worked it out as D would clearly be selected the most, followed by C, then B, and least of all A.

不过,这是行不通的。如果我这样做5000次,并计算时代每个目的地被选中的实际比例,我得到这样的:

But it doesn't work. If I do this 5000 times, and calculate the actual percentage of times each destination was selected, I get this:

呼叫 1%去到目的地A 呼叫 12%,去到目的地乙 呼叫 31%,去到目的地ç 呼叫 56%,去到目的地ð 1% of calls to go to destination A 12% of calls to go to destination B 31% of calls to go to destination C 56% of calls to go to destination D

下面是code我用来测试这一点:

Here is the code I used to test this:

// Initialise item weighting percentages
Dictionary<string, int> weighting = new Dictionary<string, int>();
weighting["A"] = 10; //10%
weighting["B"] = 20; //20%
weighting["C"] = 30; //30%
weighting["D"] = 40; //40% (total = 100%)

// Initialise data set used for each iteration
Dictionary<string, int> data = new Dictionary<string, int>();

// Initialise counts of the selected items
Dictionary<string, int> count = new Dictionary<string, int>();
count["A"] = 0;
count["B"] = 0;
count["C"] = 0;
count["D"] = 0;

Random rand = new Random();

// Loop 5000 times
for (int i = 0; i < 5000; i++) {

    // For each item, get a random number between 0 and 99
    // and multiply it by the percentage to get a
    // weighted random number.
    data["A"] = rand.Next(100) * weighting["A"];
    data["B"] = rand.Next(100) * weighting["B"];
    data["C"] = rand.Next(100) * weighting["C"];
    data["D"] = rand.Next(100) * weighting["D"];

    // Find which item came out on top and increment the count
    string sel = data.First(x => x.Value == data.Max(y => y.Value)).Key;
    count[sel]++;

    // Log, so you can see whats going on...
    if (i < 15)
        Console.WriteLine("A:{0:00000}  B:{1:00000}  C:{2:00000}  D:{3:00000}  SELECTED:{4}",
            data["A"], data["B"], data["C"], data["D"], sel);
    else if (i == 15) Console.WriteLine("...");

}

// Output the results, showing the percentage of the number
// occurrances of each item.
Console.WriteLine();
Console.WriteLine("Results: ");
Console.WriteLine("    A = {0}%", 100 * ((double)count["A"] / (double)count.Sum(z => z.Value)));
Console.WriteLine("    B = {0}%", 100 * ((double)count["B"] / (double)count.Sum(z => z.Value)));
Console.WriteLine("    C = {0}%", 100 * ((double)count["C"] / (double)count.Sum(z => z.Value)));
Console.WriteLine("    D = {0}%", 100 * ((double)count["D"] / (double)count.Sum(z => z.Value)));

借助结果是:

A:00780  B:00300  C:01740  D:03680  SELECTED:D
A:00600  B:00660  C:00060  D:03400  SELECTED:D
A:00900  B:01880  C:00510  D:00720  SELECTED:B
A:00260  B:01380  C:00540  D:01520  SELECTED:D
A:00220  B:01960  C:00210  D:02080  SELECTED:D
A:00020  B:01400  C:01530  D:00120  SELECTED:C
A:00980  B:00400  C:01560  D:03280  SELECTED:D
A:00330  B:00300  C:01500  D:03680  SELECTED:D
A:00590  B:00460  C:02730  D:02400  SELECTED:C
A:00580  B:01900  C:02040  D:01320  SELECTED:C
A:00620  B:01320  C:00750  D:01760  SELECTED:D
A:00320  B:01040  C:01350  D:03640  SELECTED:D
A:00340  B:01520  C:02010  D:03880  SELECTED:D
A:00850  B:01420  C:00480  D:03400  SELECTED:D
A:00560  B:00680  C:00030  D:00000  SELECTED:B
...

Results: 
    A = 1.44%
    B = 11.54%
    C = 30.6%
    D = 56.42%

任何人都可以提出一个方法来解决这个问题,这样的配置真正的百分比出来?

Can anyone suggest a way to fix this so that the real percentages come out as configured?

和奖励积分,任何人都可以提出一个方法做同样的事情,但没有使用的随机数,使所选目的地的顺序明确的规定。用上面的例子会输出这个序列中的每个时间:

And for bonus points, can anyone suggest a way to do something similar but not using random numbers, so that the sequence of selected destinations is clearly defined. Using the example above would output this sequence every time:

ABCDBCDCDD ABCDBCDCDD ABCDBCDCDD ABCDBCDCDD ...

(注意,该序列被均匀地分布)

(note that the sequence is evenly distributed)

感谢。 本

推荐答案

好吧,我以前在模拟做过无数次,这里的基本方法是我使用(不正确的错误检查):

Ok, I have done this numerous times before in simulations so here is the basic method I use (without proper error checking):

您需要想象一下在页面上会从0到100。现在我们正在做的是分裂这一阵容当中比例的目的地线绘制。然后,我们使用随机数来选择这条线上的一个点。其具有线的那个区域的目的地是选择之一。

You need to imagine a line draw across the page going from 0 to 100. Now what we're doing is dividing this line up proportionally amongst your destinations. We then use random numbers to choose a point on this line. The destination which has that area of the line is the one selected.

编辑:尝试在线路图

|-----------------------------------------------------|   Line 1 to 100
|-----|----------|---------------|--------------------|   Line split proportionally
0  A  10    B    30     C        60      D           100

我们可以按如下做到这一点。

We can do this as follows.

假设你的目的地的百分数都是在一个阵列,而不是在单独的变量

Assume your destination percentages are in an array, instead of in separate variables.

int totalPercentages = 0; 
int destinationsIndex = -1;
int randomNumberBetween0and100 = GetRandomNumber();
for(int i = 0; i < destinationPercentageArrays.Length; i++)
{
    totalPercentages += destinationPercentageArrays[i];
    if (totalPercentages > randomNumberBetween0and100)
    {
        destinationIndex = i;
        break;
    }
}

if (destinationIndex == -1)
{
   throw new Exception("Something went badly wrong.");
}

现在变量 destinationIndex 指向选定的目标。

Now the variable destinationIndex points to the selected destination.