How to get a portion of a group based on a three way ratio

46 Views Asked by At

I'm having a complete mental block on how to solve this problem which seems like it should be trivial...

I have three bags Apples, Oranges, Banana's and each has number a, b, c elements in each

I have a three way ratio, say 0.7, 0.2, 0.1. I want to take as many possible fruits as long as the ratio's allow but how do i calculate how many of each fruit to take?

for example:

19000 Apples, 3500 Oranges and 400 banana's at ratios 0.9, 0.09 , 0.01 , as in 90% of the final bag should be Apples, 9% should be oranges and 1% should be bannanas

How do i programmatically calculate how many to take from each bag based on lengths a, b ,c and corresponding ratios, trying to maximize total number.

edit: I came up with this I think works for different ratios a,b,c not 100% sure yet, in python:

    a = 0.9
    b = 0.09
    c = 0.01
    apple = df.loc[df['class'] == 'APPLE']
    orange = df.loc[df['class'] == 'ORANGE']
    bannana = df.loc[df['class'] == 'BANNANA']
    group = [apple,orange,bannana]
    lens = [len(a) for a in group]
    ra = [(r/a) for r in [a,b,c]]
    rb = [(r/b) for r in [a,b,c]]
    rc = [(r/c) for r in [a,b,c]]
    ratios = [ra,rb,rc]
    rad = [(r*len(apple)-le) for r,le in zip(ra,lens)]
    rbd = [(r*len(orange)-le) for r,le in zip(rb,lens)]
    rcd = [(r*len(bannana)-le) for r,le in zip(rc,lens)]
    res = [sum(x < 0 for x in r) for r in [rad,rbd,rcd]]
    index = res.index(max(res))
    lens_limited = [int(len(group[index]) * r) for r in ratios[index]]
    final_grouping = [a[0:lens_limited[i]] for a, i in enumerate(group)]
1

There are 1 best solutions below

0
On BEST ANSWER

At first examination, your question can be considered as a linear programming issue with constraints ; with your numerical data (with $x,y,z$ the resp. number of apples, oranges and bananas that have to be selected):

$$\text{maximize} \ \ x+y+z \ \ \text{under constraints:} \ (*) \ \begin{cases}x/(x+y+z)=0.9\\ y/(x+y+z)=0.09\\ z/(x+y+z)=0.01\end{cases}$$

with range constraints: $$x \leq 19000, \ \ y \leq 3500, \ \ z \leq 400.$$

(see remark at the bottom.)

But in fact, it is not useful to consider this issue using linear programming because (*) has the consequence that $x,y,z$ have to be proportional to $0.9;0.09, 0.01$. Thus, there is a common factor $a$ such that

$$\tag{1}x=0.9 a, y=0.09 a, z=0.01 a.$$

As a consequence, the above range constraints are transformed into:

$$\tag{2}0.9a \leq 19000, \ \ 0.09a \leq 3500, \ \ 0.01a \leq 400$$

$$ \iff \ \ a=\min \left(\tfrac{19000}{0.9}, \tfrac{3500}{0.09}, \tfrac{400}{0.01} \right)=21111.$$

Thus (2) gives $x=19000, y=1900, z=211$.

In this case, the limiting factor is the number of apples.

The general case with litteral values follows easily from this numerical example.

Remark: (*) is equivalent to the (homogeneous) linear system $$\begin{cases}0.1 x-0.9y-0.9z&=&0\\-0.09x+0.91y-0.09z&=&0\\0.01x+0.01y+0.99z&=&0\end{cases}$$

whose non-trivial solution is $(x,y,z)=a(0.9, 0.09, 0.01)$, of course...