Puzzle: Marketing Madness

Puzzle: Marketing Madness

Two main players in the fruit industry are seeking to increase their sales in an overall growing market. The incumbent is Amazing Apples Inc.; the up-and-coming fruit company is Better Bananas LLC. Better Bananas has hired your firm to optimize their marketing campaign. But beware: marketing is madness, and you are bound to be surprised!


Better Bananas has designated $500,000 for their campaign. They are targeting three different age groups: TikTokers (T, under 30), Hashtaggers (H, 30–50), and SilverSurfers (S, over 50). Now they need to decide how to distribute their budget to these groups in increments of k = $50,000. The problem is that when they launch their campaign, they are sure that Amazing Apples will counter with their own campaign. And Amazing Apples has deep pockets; they can spend $1 million on their own marketing campaign.

Each company is only aiming to maximize its own sales; there is no incentive to hurt the sales of the other company. However, by marketing its own product, each company inadvertently diminishes the effect of the other's marketing.

Let us denote the marketing spend per age group G by company X with X_G (e.g., B_T for Better Bananas' spend on TikTokers or A_S for Amazing Apples' spend on SilverSurfers). Moreover, recall that k = 50,000.

Then, for Better Bananas, the expected growth in sales is given by this formula:

Bananas [in thousand pounds] = 300 * B_T/(A_T+k) + 350 * B_H/(A_H+k) + 400 * B_S/(A_S+k)

The formula for Amazing Apples is:

Apples [in thousand pounds] = 250 * A_T/(B_T+k) + 500 * A_H/(B_H+k) + 750 * A_S/(B_S+k)

The only additional information we have is that Better Bananas cannot spend more than $300,000 on any one age group, while Amazing Apples can spend at most $500,000 on any individual age group. After these maxima are reached, no further increase in sales is to be gained.

The simple question for you is: How much money should Better Bananas allocate to each age group? You have 10 tokens of $50,000 each to distribute and cannot allocate more than 6 tokens to any one age group.


Scroll down for the solution.


Maybe think a bit more? The solution is not obvious.


The optimal allocation is $50,000 to TikTokers, $150,000 to Hashtaggers, and $300,000 to SilverSurfers. The optimal reply by Amazing Apples then is to allocate $500,000 to TikTokers and an equal amount to Hashtaggers. With these allocations, we are expecting an increase in sales of 2.52 million pounds of bananas and 2.5 million pounds of apples.


Better Bananas' designation of $300,000 to SilverSurfers will not surprise, as the marketing spend on this age group leads to the largest increase in sales (the biggest bang for the buck). But why is it not optimal to spend the entire remaining $200,000 on the Hashtaggers?

The answer is simple: If we were to allocate $200,000 to the Hashtaggers, then it would be better for Amazing Apples to compete with us in the SilverSurfer than in the Hashtaggers age group. Particularly, Amazing Apples' optimal allocation of their $1 million would then be to spend $500,000 on TikTokers and the same amount on SilverSurfers. This would lead to increased sales of only 1.61 million pounds of bananas and a whopping 3.57 million pounds of apples (where the primary sales driver is that they have no competition marketing TikTokers).

Therefore, by deliberately lowering our marketing spend in the Hashtaggers segment, we leave enough room for Amazing Apples to invest here instead of in the SilverSurfer segment, which we care more about. Stated simpler: don't go bananas with your marketing.


This example shows how our business results can depend on the actions of other players who are not necessarily antagonists but who pursue their own objectives. There are many surprising and often counterintuitive effects that can occur in such a setting. Thankfully, InsideOpt Seeker(TM) can model these problems with ease. Below, you will find the complete model for this problem.

 1 import seeker as skr
 3 env = skr.Env("Seeker_License.sio")
 4 k = 50000
 5 investments_B = [env.ordinal(0,6)*k for _ in range(3)] 
 6 obj_A_const = [250, 500, 750]
 7 obj_A = [ obj_A_const[i]/(investments_B[i]+k) for i in range(3) ]
 8 var_bounds = env.convert([0, 10*k, 0, 10*k, 0, 10*k])
 9 row_bounds = env.convert([0, 1000000])
10 matrix = env.convert([[1,1,1]])
11 opt_model_A = env.lp(obj_A, var_bounds, row_bounds, matrix, maximize=True)
12 solution_A_value = opt_model_A.get_objective()
13 investments_A = opt_model_A.get_solution()
14 obj_B_const = [300, 350, 400]
15 env.enforce_leq(env.sum(investments_B),500000)
16 obj_B = env.sum([ obj_B_const[i] * investments_B[i] / (investments_A[i]+k) for i in range(3) ])
18 env.maximize(obj_B,1)
20 print("Investments B:", [investments_B[i].get_value() for i in range(3)])
21 print("Extra Bananas [1,000 pounds]:",obj_B.get_value())
22 print("Investments A:", [investments_A[i].get_value() for i in range(3)])
23 print("Extra Apples [1,000 pounds]:",solution_A_value.get_value())
24 print("Evaluations:", env.get_number_evaluations())

Note that, in Seeker(TM), you can specify terms that conduct their own separate optimization. In Line 11, we specify a linear programming optimization model that expresses that Amazing Apples is pursuing its own separate objective function, which itself depends on our investment decisions. We obtain access to the optimal investment decisions from Amazing Apples in Line 13.

After optimizing our own objective for 1 second in Line 18, we obtain this output:


Investments B: [50000.0, 150000.0, 300000.0]

Extra Bananas [1,000 pounds]: 2522.727272727273

Investments A: [500000.0, 500000.0, 0.0]

Extra Apples [1,000 pounds]: 2500.0000

Evaluations: 45405


Overall, thanks to Seeker(TM), we increased the effectiveness of our campaign by over 55%. Not bad for a day's work!