I’m working on a simple optimization problem for selecting bids from advertising campaigns on available ad spaces, subject to several constraints:
(1) only one bid per ad space can be selected,
(2) campaigns are subject to a maximum total spend budget, and
(3) there is a price minimum for each available ad space for each campaign.
Here’s the code I created and ran in Google Colab:
import amplpy
from amplpy import AMPL, ampl_notebook
ampl = ampl_notebook(
modules=["coin", "highs", "cbc"], # modules to install
license_uuid="LICENSE UUID", # license to use
) # instantiate AMPL object and register magics
ampl = AMPL()
ampl.eval(r"""
# Define sets
set ADSPACES; # Unsold Advertisement inventory
set CAMPAIGNS; # Advertising campaigns, bidding on inventory space
# Define parameters
param BidAmount {CAMPAIGNS, ADSPACES} >= 0; # Amount bid by each CAMPAIGN on each ADSPACE
param PriceFloor {CAMPAIGNS, ADSPACES} >= 0; # Price floors, per CAMPAIGN per ADSPACE
param Budget {CAMPAIGNS} >= 0; # Maximum budget for each campaign
# Define decision variables
var BidDecision {CAMPAIGNS, ADSPACES} binary;
# Define objective function
maximize TotalRevenue:
sum {c in CAMPAIGNS, i in ADSPACES} BidAmount[c, i] * BidDecision[c, i];
# Define constraints
subject to OnlyOneWinnerPerAdSpace {i in ADSPACES}:
sum {c in CAMPAIGNS} BidDecision[c, i] = 1;
subject to PriceFloorConstraint {c in CAMPAIGNS, i in ADSPACES}:
BidAmount[c, i] * BidDecision[c, i] >= PriceFloor[c, i];
subject to CampaignBudgetConstraint {c in CAMPAIGNS}:
sum {i in ADSPACES} BidAmount[c, i] * BidDecision[c, i] <= Budget[c];
# Data
data;
set ADSPACES := A1_1, A1_3, A1_6, A2_2, A2_6, A2_7, A3_4, B1_1, B1_3, B1_6, B2_2, B2_6, B2_7, B3_4;
set CAMPAIGNS := CampaignX, CampaignY, CampaignZ;
param BidAmount:
A1_1 A1_3 A1_6 A2_2 A2_6 A2_7 A3_4 B1_1 B1_3 B1_6 B2_2 B2_6 B2_7 B3_4 :=
CampaignX 3600 2700 3240 2400 3090 3090 3900 2100 2850 2760 3150 3030 3030 3300
CampaignY 3250 3300 3150 3500 3050 3050 3000 3100 3150 3050 2900 2900 2900 3200
CampaignZ 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
param PriceFloor:
A1_1 A1_3 A1_6 A2_2 A2_6 A2_7 A3_4 B1_1 B1_3 B1_6 B2_2 B2_6 B2_7 B3_4 :=
CampaignX 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000
CampaignY 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000
CampaignZ 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000 3000;
param Budget := CampaignX 30000, CampaignY 30000, CampaignZ 30000;
""")
ampl.solve(solver="cbc") #highs, cplec, cbc, bonmin, base
print(f"{ampl.getVariables()}")
# Print output
print(ampl.getVariable("BidDecision").get_values())
When I run this code, I get the following error message:
RuntimeError: Unexpected end of file while reading AMPL output.
Usually this is caused by the termination of the underlying AMPL interpreter.
The problem seems to be linked to the PriceFloor
constraints. I believe this is because the code will execute properly if I edit the problem and program to specify the price floor generically for each ad space instead of per ad space and per campaign. Reference the code below for this example.
ampl.eval(r"""
# Define sets
set ADSPACES; # Unsold Advertisement inventory
set CAMPAIGNS; # Advertising campaigns, bidding on inventory space
# Define parameters
param BidAmount {CAMPAIGNS, ADSPACES} >= 0; # Amount bid by each CAMPAIGN on each ADSPACE
param PriceFloor {i in ADSPACES} >= 0; # Price floors, should be extended to be per campaign
param Budget {CAMPAIGNS} >= 0; # Maximum budget for each campaign
# Define decision variables
var BidDecision {CAMPAIGNS, ADSPACES} binary;
# Define objective function
maximize TotalRevenue:
sum {c in CAMPAIGNS, i in ADSPACES} BidAmount[c, i] * BidDecision[c, i];
# Define constraints
subject to OnlyOneWinnerPerAdSpace {i in ADSPACES}:
sum {c in CAMPAIGNS} BidDecision[c, i] = 1;
subject to PriceFloorConstraint {i in ADSPACES}:
sum {c in CAMPAIGNS} BidAmount[c, i] * BidDecision[c, i] >= PriceFloor[i];
subject to CampaignBudgetConstraint {c in CAMPAIGNS}:
sum {i in ADSPACES} BidAmount[c, i] * BidDecision[c, i] <= Budget[c];
# Data
data;
set ADSPACES := A1_1, A1_3, A1_6, A2_2, A2_6, A2_7, A3_4, B1_1, B1_3, B1_6, B2_2, B2_6, B2_7, B3_4;
set CAMPAIGNS := CampaignX, CampaignY, CampaignZ;
param BidAmount:
A1_1 A1_3 A1_6 A2_2 A2_6 A2_7 A3_4 B1_1 B1_3 B1_6 B2_2 B2_6 B2_7 B3_4 :=
CampaignX 3600 2700 3240 2400 3090 3090 3900 2100 2850 2760 3150 3030 3030 3300
CampaignY 3250 3300 3150 3500 3050 3050 3000 3100 3150 3050 2900 2900 2900 3200
CampaignZ 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
param PriceFloor :=
A1_1 3000
A1_3 3000
A1_6 3000
A2_2 3000
A2_6 3000
A2_7 3000
A3_4 3000
B1_1 3000
B1_3 3000
B1_6 3000
B2_2 3000
B2_6 3000
B2_7 3000
B3_4 3000;
param Budget := CampaignX 30000, CampaignY 30000, CampaignZ 30000;
""")
Please help me understand why the code is giving the error.