Eva recently discovered a shelf full of bottles of wine in the cellar. She counted 24 bottles of Rioja and 17 bottles of Malbec. She also noticed the price labels on the bottles: The price of one bottle of Rioja was $25 and one bottle of Malbec costs $49. Suddenly, she realized that her husband had spent $2000 a week ago for just this wine. How many bottles did the husband already drink? (Let x and y be the number of bottles of Rioja and Malbec bought by the husband.)
There are two kinds of wine bottles: the Rioja costs $25 per bottle, and the Malbec costs $49 per bottle. Eva wants to know how many of each he had bought. Then she can easily derive from the remaining bottles in the cellar, how many her husband had already drunk.
For this let’s introduce 2 variables for the quantities of the two kinds of wine:
The two variables (the unknown quantities) are the number of bottles of Rioja and the number of bottles of Malbec (before he drank some of them, they are – say x and y. These are integer variables because we consider entire bottles only.
The husband spent 25x for the Rioja.
He spent 49y for the Malbec.
In total he spent 25x + 49y which must give 2000. Hence, the constraint is: 25x + 49y = 2000. This is the unique condition.
The result then is x - 24 and y - 17 emptied bottles.
model math01 "Drunken Husband";
integer variable x; y;
constraint A: 25*x+49*y = 2000;
solve;
Write('He drank %d bottles of Rioja and %d Malbec.' ,
x-24 , y-17);
end
The husband bought 31 bottles of Rioja (x = 31) at $25 and 25 bottles of Malbec (y = 25) at $49. Altogether he spends $2000 as required by the problem. The solution can easily be verified: 25 ⋅ 31 + 49 ⋅ 25 = 2000. It is a little bit more involving to verify that this solution is unique. To check, we transform the constraint to
Suppose now x is smaller than 31. It follows that y must be larger than 25. The next larger value for y for which the division is integer must be 50. However, the nominator becomes negative (2000 - 49 ⋅ 50 < 0). Hence, x = 31 is the smallest possible number. Similarly, suppose that x is larger than 31, then y must be smaller then 25. Again, in this case the next smaller value for y must be 0 for which the division is integer. However this is not possible, since there are 17 bottles of Malbec in the cellar (y ≥ 17). Hence x = 31 is the largest possible number. It follows that x must be exactly 31 and therefore y must be 25. The number of emptied bottles of Rioja is 7, and of Malbec is 8.
The solution can also be illustrated by a x-y-graph. Run the model xmath01 and zoom into the result graph (see Figure 1). You will see that the line 25x + 49y = 2000 touches an integer grid point only two times: at (31, 25) and at (80, 0). This means that they are the only two integer solutions with positive numbers. (This model also illustrates how LPL can be used to draw simple graphs.)
In the LPL code, the keyword solve is used to find any feasible solution, if one exists. An arbitrary solution is presented if there are more than one feasible solutions. The solution is returned using the function Write(...). This function writes the solution to a file called NOM-filen (the same filename as the LPL model but with extension ’nom’. The first parameter of Write is a string that contains 2 “placeholders”, such as %d to print the values of x- 24 and y - 17. In the variable declaration the keyword integer is necessary to make sure that there are whole numbers of bottles, otherwise there would be an infinite number of solutions.
Verify that there is no solution with x ≤ 30 by modifying the model.
Verify that (x,y) = (31, 25) and (x,y) = (80, 0) are the only two solutions for this problem using the model, supposing the husband spends all the money.
Suppose, the husband can spend at most $333 and he likes to buy an equal numbers of bottles of Rioja and Malbec. How many bottles of each kind can he buy now?
Suppose the husband wants to buy as many bottles as he can for $997. How many can he buy of each type? Guess the solution first before solving the problem!
You should add the constraint:
constraint B: x <= 30;
then solve the problem. No output is produced and the LOG-file says that the problem is infeasible, which means that no solution exists under the given constraints.
Minimizing x confirms that x cannot be smaller than 31. Adding the following bound as a new constraint:
constraint B: x >= 32;
gives the second solution: (80, 0). Hence, x can only be 31 or 80. For our problem, the second solution is not valid, since y must be at least 17.
He can buy 4 bottles of each wine. The model then must be changed to:
model math01b;
integer variable x; y;
constraint A: 25*x+49*y <= 333;
constraint B: x = y;
maximize obj: x+y;
Write('(x,y) = (%d,%d)', x,y);
end
Note that he could not spend all the money. He has $37 left, and he spent $296.
The guess is that he should spend all his money only for Rioja for $25 and none for Malbec for $49, because the first kind is cheaper. To verify this, you need to modify the model in the following way:
model math01d;
integer variable x; y;
constraint A: 25*x+49*y <= 997;
maximize obj: x+y;
Write('Solution is: (x,y) = (%d,%d)', x,y);
end
He bought 39 bottles of Rioja (x = 39) and none of Malbec as expected. And he has $22 left.
[1] MatMod. Homepage for Learning Mathematical Modeling : https://matmod.ch.
[2] Hürlimann T. Reference Manual for the LPL Modeling Language, most recent version. https://matmod.ch/lpl/doc/manual.pdf.