Search code examples
mathematical-optimizationlinear-programmingnonlinear-optimizationinteger-programming

Can this specific Linear Program constraint be expressed?


Thanks for your time.

I have a linear program and no idea how I could express a form of constraint and even if it's possible. Maybe someone here know a solution.

A company assembly and sells a mixture which is composed of 3 ingredients, a, b and c, with a = b = c.
Each ingredients can come from 2 factories : f1 and f2.
The cost of each ingredients are fluctuating all day and are different between each factories.
Each factory provide the costs for each ingredients in the form of a list of couples : (cost, availableAmount).

The constraint I want to express (without impacting the existing objective function) and I don't know how to it is :
Avoid to choose manufacting costs that are greater that my selling price.

For example at time t, the costs could be :

- for ingredient a :  
f1 : (10$, 5.1), (11$, 10.2), (13$, 20.5)  
f2 : (11$, 1.), (12$, 15.2), (13$, 6.9)  
- for ingredient b :  
f1 : (15$, 8.3), (16$, 20.), (18$, 10.7)  
f2 : (15$, 4.2), (16$, 15.1), (18$, 19.3)  
- for ingredient c :  
f1 : (31$, 2.), (34$, 3.5), (37$, 14.9)  
f2 : (30$, 4.7), (32$, 9.2), (35$, 12.4) 

I would like to get the best repartition for two input constants which are : maximumAllowedQuantity and maximumAllowedCost.
But currently I only handle maximumAllowedQuantity and I would like to also handle maximumAllowedCost (this is the purpose of my question).

The resulting solution composed of amounts for each costs will be in the output variables :

amountAF1_1, amountAF1_2, amountAF1_3  
amountAF2_1, amountAF2_2, amountAF2_3  
amountBF1_1, amountBF1_2, amountBF1_3  
amountBF2_1, amountBF2_2, amountBF2_3  
amountCF1_1, amountCF1_2, amountCF1_3  
amountCF2_1, amountCF2_2, amountCF2_3  

For example using the example data provided, and for the input maximumAllowedQuantity = 15 (without maximumAllowedCost constraint cause I don't know how to formulate it and this is what I ask), based on some objectives of the moment (for example : I prefer to divide equitably the amounts between factories for the same total cost and not favour one factory),
I could get :

amountAF1_1 = 5.1, amountAF1_2 = 4.9, amountAF1_3 = 0.  
amountAF2_1 = 0., amountAF2_2 = 5., amountAF2_3 = 0.  
amountBF1_1 = 5., amountBF1_2 = 0., amountBF1_3 = 0.  
amountBF2_1 = 4.2, amountBF2_2 = 5.8, amountBF2_3 = 0.  
amountCF1_1 = 2., amountCF1_2 = 3.5, amountCF1_3 = 2.  
amountCF2_1 = 4.7, amountCF2_2 = 2.8, amountCF2_3 = 0.  

Which I can summarise cost-wise to :

5.1a at 10$, 4.9a at 11$, 5.0a at 12$,  
9.2b at 15$, 5.8b at 16$,  
4.7c at 30$, 2.0c at 31$, 2.8c at 32$, 3.5c at 34$, 2.0c at 37$

If we decompose the resulting mixtures by cost we get :

4.7 mixtures at 10 + 15 + 30 = 55$,  
0.4 mixtures at 10 + 15 + 31 = 56$,  
1.6 mixtures at 11 + 15 + 31 = 57$,  
2.5 mixtures at 11 + 15 + 32 = 58$,  
0.3 mixtures at 11 + 16 + 32 = 59$,  
0.5 mixtures at 11 + 16 + 34 = 61$,  
3.0 mixtures at 12 + 16 + 34 = 62$,  
2.0 mixtures at 12 + 16 + 37 = 65$, 

Here the maximum cost is 65$.
But if my selling price is 60$, in order to avoid loosing money :
How can I add the constraint maximumAllowedCost = 60$ ?

nb : we cannot simply take the previous result (without maximumAllowedCost constraint) and remove the amounts at costs > 60$, cause my objective function will give another repartition for quantities at costs <= 60 if the total quantity is smaller : here 9.5 (15 - 0.5 - 3.0 - 2.0) instead of 15 before.
...

Thanks


Solution

  • Let me restate your question. Each factory f gives you a list of bids (price quantity pairs) for the ith ingredient. Let's write (and index) the jth bid as

     (price[j, f, i], quantity[j, f, i])
    

    It sounds like your goal is to decide what bids to accept, subject to constraints on making a profit.

    Let x[j, f, i] represent the quantity of bid j of ingredient i that you purchase from factory f. You can't purchase a negative amount of an ingredient and you can't purchase more than quantity the factory offers in that bid so we have

     0 <= x[j, f, i] <= quantity[j, f, i] for all j, f, i
    

    The xs are your decision variables.

    The cost you pay for accepting the jth bid is price[j, f,i] * x[j, f, i].

    So the total cost you pay to all factories for the ingredients is given by

    sum_{j, f, i} price[j, f, i]*x[j, f, i]
    

    Let m represent the amount of mixture you create with these ingredients. m will be a decision variable. The mixture is composed of equal parts of each ingredient. So the amount of mixture you can create is limited by the scarcest ingredient. That is

    m <= sum_{j, f} x[j,f,i] for all i
    

    You make $60 (say) for selling one unit of the mixture. So your revenue is given 60*m.

    The profit you make is revenue - cost or

    60*m - sum_{j, f, i} price[j, f, i]*x[j, f, i]
    

    To ensure the manufacturing costs are less than or equal your selling price, you simply ensure your profit is non-negative. Or

    60*m - sum_{j, f, i} price[j, f, i]*x[j, f, i] >= 0
    

    Those are your constraints, and you can put any objective on it you like. For example you might want to maximize your profit while trying to divide your purchases as equally as possible among the factories.

    To do this let y[f] represent the quantity purchased from factory f. Then

    y[f] == sum_{j, i} x[j, f, i]  for all f
    

    For each pair of factories f1, f2 we can compute the difference in the quantity purchased as z[f1, f2] where

    z[f1, f2] >= y[f1] - y[f2]  for all factory pairs (f1, f2)
    z[f1, f2] >= y[f2] - y[f1]  for all factory pairs (f1, f2)
    

    This gives us the following linear program

    minimize      -p + sum_{all factory pairs f1, f2}  z[f1, f2]
    x,m,y,z,p
    
    subject to    p == 60*m - sum_{j, f, i} price[j, f, i]*x[j, f, i]
                  y[f] == sum_{j, i} x[j, f, i] for all f
                  m <= sum_{j, f} x[j, f, i] for all i
                  z[f1, f2] >= y[f1] - y[f2] for all factory pairs (f1, f2)
                  z[f2, f1] >= y[f2] - y[f1] for all factory pairs (f1, f2)
                  x[j, f, i] <= quantity[j, f, i] for all j, f, i                   
                  0 <= x[j, f, i] for all j, f, i
                  0 <= m
                  0 <= y[f] for all f
                  0 <= p