views:

185

answers:

3

Hi all,

I have an dictionary of lists of objects as shown below:

IDictionary<string, IList> MyItemDictionary

I work out the percentages by doing a for each through the dictionary with the code below:

IList<double> percentages = new List<double>();    

foreach(KeyValuePair<string, IList> pair in MyItemDictionary)
{
    double percentage = (100d/totalItemsCount)*pair.Value.Count;
    percentages.Add(percentage);
}

Basically I need to process the percentages list and round each percentage to a whole number BUT have them add up to 100. Accuracy is not of the highest importance but a sub 1 percentage i.e. 0.45 needs to be rounded to 1.

Does anyone know how to do this?

Thanks for your time and I look forward to your responses!

Adam

+2  A: 

If your percentage list ends up containing 1.5 + 1.5 + .. + 1.5 = 100.0 and you were to round them into 2 + 2 + .. + 2, you would end up with 134 as the total sum (~67 entries), not 100. The way to fix this, is to distribute the error (134-100=34) among the existing percentages. In this case, you would subtract 1 from 34 of the percentages so you end up with a series of 1 + 2 + 1 + 2 + .. + 2 = 100.0.

To find what "every other" means you simply do int(numberOfPercentages / theError) and that should give you the interval.

Also, you must take care not to subtract anything from your sub 1 percentages.

Oh, and in case all your percentages are sub 1, the problem cannot be solved :-(

Martin Wickman
+1  A: 

Can you have an "Other" or "Misc" category? If you have many small percentages, and you round them all up or down, you will accumulate a huge error as wic pointed out. You might need a minmimum threshold beyond which you lump everything together as miscellaneous stuff.

Otherwise, I second wic's idea about summing up the percentages to find the error and then distributing the error over the largest percentages.

Paul Williams
That would also neatly solve the issue of when there are 101 items in the list
Ruffles
Thats an interesting proposal... I may beable to use that. Thank you!
+1  A: 

Take a look at how seats in a parliament are assigned based on votes for proportional representation. I would suggest the largest remainder method, because it uses time proportional to the number of items in your list.

starblue