Представление представляет собой набор из N элементов в словаре и связанных с ним вхождений. Теперь я должен назначить точно X слотов для каждого элемента на основе его общей вероятности, но не менее 1 слота на элемент.Распределите N элементов по множеству по крайней мере один раз
Вот что я придумал:
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
public static class Program
{
public static void Main(string[] args)
{
var dict = new Dictionary<char,int>();
dict.Add('a' , 10); dict.Add('b' , 0);
dict.Add('c' , 4); dict.Add('d' , 1);
dict.Add('e' , 9); dict.Add('f' , 0);
var distributionMap = Distribute(dict , 40);
}
public static Dictionary<T,int> Distribute<T>(Dictionary<T,int> occurMap , int slots)
{
var freeSlots = slots - occurMap.Count;
var total = occurMap.Sum(x => x.Value);
var distMap = new Dictionary<T,int>();
foreach(var pair in occurMap)
{
var probability = (double)pair.Value/total;
var assignedSlots = probability * freeSlots;
distMap[ pair.Key ] = (int)(1 + assignedSlots);
}
Debug.Assert(distMap.Select(x => x.Value).Sum() == slots);
return distMap;
}
}
Однако утверждают триггеры, как преобразование из double
в int
обрезает вероятность в какой-то момент.
Как сопоставить все слоты хотя бы один раз с элементами на основе их подсчета?
Вероятность - это доля, поэтому она должна быть фракцией или умножаться на 100, чтобы получить процент. Итого нужно перевести в double, потому что C# будет преобразовывать значение пара.value/total в целое число, если total является целым числом. Вы действительно хотите, чтобы пара.value/total являлось нецелым. – jdweng
Math.Ceiling() может быть? – Master117
@jdweng Почему мне нужен процент? Кроме того, вероятности уже удваиваются, поскольку я заставляю одного операнда удваивать. – nonsensation