问题描述
我的工作,涉及转接电话到多个目标的项目。
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.
这篇关于计算该项目旁边的百分比分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!