我有一種情況,我需要在M個插槽間平均分配N個項目。每個項目都有自己的分配%。爲了討論的目的,假設有三個項目(a,b,c),其中各個百分比(50,25,25)均勻分佈在20個時隙中。因此需要分配10 X a,5 X b & 5 X c。其結果將是如下:如何平均分配項目,沒有隨機數
1. a
2. a
3. c
4. b
5. a
6. a
7. c
8. b
9. a
10. a
11. c
12. b
13. a
14. a
15. c
16. b
17. a
18. a
19. c
20. b
,我掙扎的部分是槽的數量,項目和百分比數都可以改變,當然百分比總是合計達100%。我寫的代碼導致後面的輸出,它總是被重新加權,以支持具有最高百分比的項目。任何想法都會很棒。
1. a
2. b
3. c
4. a
5. b
6. c
7. a
8. b
9. c
10. a
11. c
12. b
13. a
14. b
15. c
16. a
17. a
18. a
19. a
20. a
編輯 這是我的代碼目前的模樣。正如我前面提到的那樣,反向加權分配結果。對於一個小環境,我試圖平均分配廣告節目。因此,每次使用相同輸入的運行必須得到完全相同的輸出。這就是排除使用隨機數的原因。
foreach (ListRecord spl in lstRecords){
string key = spl.AdvertiserName + spl.ContractNumber + spl.AgencyAssignmentCode;
if (!dictCodesheets.ContainsKey(key)){
int maxAssignmentForCurrentContract = weeklyList.Count(c => (c.AdvertiserName == spl.AdvertiserName) && (c.AgencyAssignmentCode == spl.AgencyAssignmentCode)
&& (c.ContractNumber == spl.ContractNumber) && (c.WeekOf == spl.WeekOf));
int tmpAssignmentCount = 0;
for (int i = 0; i < tmpLstGridData.Count; i++)
{
GridData gData = tmpLstGridData[i];
RotationCalculation commIDRotationCalc = new RotationCalculation();
commIDRotationCalc.commercialID = gData.commercialID;
commIDRotationCalc.maxAllowed = (int)Math.Round(((double)(maxAssignmentForCurrentContract * gData.rotationPercentage)/100), MidpointRounding.AwayFromZero);
tmpAssignmentCount += commIDRotationCalc.maxAllowed;
if (tmpAssignmentCount > maxAssignmentForCurrentContract)
{
commIDRotationCalc.maxAllowed -= 1;
}
if (i == 0)
{
commIDRotationCalc.maxAllowed -= 1;
gridData = gData;
}
commIDRotationCalc.frequency = (int)Math.Round((double)(100/gData.rotationPercentage));
if (i == 1)
{
commIDRotationCalc.isNextToBeAssigned = true;
}
lstCommIDRotCalc.Add(commIDRotationCalc);
}
dictCodesheets.Add(key, lstCommIDRotCalc);
}else{
List<RotationCalculation> lstRotCalc = dictCodesheets[key];
for (int i = 0; i < lstRotCalc.Count; i++)
{
if (lstRotCalc[i].isNextToBeAssigned)
{
gridData = tmpLstGridData.Where(c => c.commercialID == lstRotCalc[i].commercialID).FirstOrDefault();
lstRotCalc[i].maxAllowed -= 1;
if (lstRotCalc.Count != 1)
{
if (i == lstRotCalc.Count - 1 && lstRotCalc[0].maxAllowed > 0)
{
//Debug.Print("In IF");
lstRotCalc[0].isNextToBeAssigned = true;
lstRotCalc[i].isNextToBeAssigned = false;
if (lstRotCalc[i].maxAllowed == 0)
{
lstRotCalc.RemoveAt(i);
}
break;
}
else
{
if (lstRotCalc[i + 1].maxAllowed > 0)
{
//Debug.Print("In ELSE");
lstRotCalc[i + 1].isNextToBeAssigned = true;
lstRotCalc[i].isNextToBeAssigned = false;
if (lstRotCalc[i].maxAllowed == 0)
{
lstRotCalc.RemoveAt(i);
}
break;
}
}
}
}
}
}
}
編輯2 想在這裏澄清我的要求。目前,由於項目'a'將被分配10次,這是所有三個項目中最高的,在分配結束時,項目16-20全部只被分配了'a'。正如評論中提到的那樣,我試圖實現更「均勻」的分配。
只需在算出數學後洗牌收集?另外,如果你發佈你的代碼,它會幫助我們。 – maccettura
是「沒有隨機數字」的要求,或者你認爲它不會工作根據您的發佈結果? –
「這是總是重新加權的項目與最高百分比」好耶,是不是百分點的點?你不會平均增加兩倍嗎? –