Assign a value according to a defined ratio

I have one scenario here. Let me explain with a small example.

I have 10 pens, I have to give it to 3 people. The ratio of these people is 6: 6: 1 means that if I give 1 pen to Person C, I must provide 6-6 people for person A and person B.

I tried to solve this problem using a simple calculation, which I described below.

PerPersonPen = (TotalCountofPens * PerPersonRatio)/(SumofAllPersonsRatio) Person A =(Int) (10*6)/13 = 4 Person B = (Int) (10*6)/13 = 4 Person C = (Int) (10*1)/13 = 0 

Here Person C will get 0 handles, but this should not happen. I would like for person A and B to have 4 pens that are right. But Person C should also get 1 pen.

This happens if any person has 1 ratio of the ratio compared to others.

Can someone help me figure this out? Or how can I achieve this?

+5
source share
4 answers

A simple method is to count the number of pens that each person should receive. Then, while they are feathers for distribution, you give one to the person who should receive most of the pens.

Here is an example of your example:

60/13 , 60/13, 10/13 β†’ 1 , 0, 0

47/13, 60/13 , 10/13 β†’ 1, 1 , 0

47/13 , 47/13, 10/13 β†’ 2 , 1, 0

34/13, 47/13 , 10/13 β†’ 2, 2 , 0

34/13 , 34/13, 10/13 β†’ 3 , 2, 0

21/13, 34/13 , 10/13 β†’ 3, 3 , 0

21/13 , 21/13, 10/13 β†’ 4 , 3, 0

8/13, 21/13 , 10/13 β†’ 4, 4 , 0

8/13, 8/13, 10/13 β†’ 4, 4, 1

8/13 , 8/13, -3/13 β†’ 5 , 4, 1

Update If you want each person to receive at least one pen, if possible, first give one pen to each person, indicating the priority to those who need the most pens, if you do not have enough pens for everyone. Then proceed as described above.

+3
source

Laurent G gave a very useful link to the Math Stack Exchange in the comments section. How to round numbers is pretty

This post implies the following algorithm:

  • For each person, calculate the coefficient x_i she should get ( x_i = her share/sum of shares )
  • Set C_min = numberOfPens and C_max large enough so that sum_i (floor(x_i*C_max)) > numberOfPens ( C_max = numberOfPens + 1/(min x_i) should work)
  • Do a dichotomous search between C_min and C_max until you find C so that sum_i (floor(x_i*C)) = numberOfPens

This, however, may not work when there are connections (for example, in your example, where two relations have a value of 6/13). But what you can do is add very little random noise (you add or subtract less than half the smallest non-zero gap existing between your original coefficients) to your coefficients to break the ties and get the result as a whole, which will be β€œalmost fair” .

EDIT: I noticed that my initial C_max selection was wrong, so I fixed it with something that works. However, I think there is room for improvement. You can also find the initial C_max by increasing k 2^k numberOfPens until the criterion ( sum_i(floor(x_i*C_max)) > numberOfPens ) is sum_i(floor(x_i*C_max)) > numberOfPens .

+1
source

When looking at your example, it is clear that everyone should get at least the rsult you have calculated. And only a few will get more.

I suggest the following algorithm:

  • calculate how much each preson should get in double size. The same as without a throw.
  • sum the notional sum of all persons (8 in our example).
  • Sort people by Mantissa (after the dot).
  • For the first k faces Use Math.Ceiling(assigned value) , where k is the desired value is the amount calculated in step 2. 10-8 in our example.
  • For others, regular listing is used, for example (int) (assigned value) .
0
source

Sort of

 int_weights = [6, 6, 1] total_weights = sum(int_weights) to_share = 10 still_to_share = to_share left_weight_total = total_weights shares = [] for weight in int_weights: s = int(0.5 + (float(still_to_share) * weight / left_weight_total)) still_left -= s left_weight_total -= weight shares.append(s) 

This gives a fairly, but not entirely fair (which cannot be achieved using links, see the link published in the commentary to the Question)

 shares 

[5, 4, 1]

 sum(shares) 

0

If you want to achieve fairness in relations, the best result would be [4, 4, 2] (or [5, 5, 0] [: auto_censored_but_not_totally:] ;-)?), Which you can achieve by sorting and taking into account the previous distribution ( s). Until I get a good argument to be so choosy, I would keep a solution like the one shown above.

-1
source

Source: https://habr.com/ru/post/1266153/


All Articles