Let's say you own a fruit store and want to find the optimum number of apples to sell each day. However, there is a different price associated depending on how many apples are sold (you have no say in these bundled price pairs).
e.g.
Day_1 Day_2
Daily_price_offers = [[(5 apples,$8),(10 apples,$4)] , [(7 apples,$6),(10 apples,$4)], ...]
Now, suppose a customer wishes to purchase 7 apples on Day 1 and 9 apples on Day 2, then they are priced based on the previous bundled price (like a step-wise function). So, in this case they pay $8 on the first day and $6 on the second day.
The Goal
What is the best way to set this up in Pyomo, so that a step-wise function is applied when interpolating? I have created a solution that picks the highest value of the given bundles each day, but I am after the best way for finding the in-between values. Note, this would mean a new variable would need to be defined for the optimal number of apples sold each day.
This example uses integers, but it would be great to be able to handle floating point quantities as well (for different applications).
My Attempt
from pyomo.environ import *
# Inputs
daily_price_offer = [[(5,8),(10,4)],[(7,6),(10,4)],[(4,6),(10,3)]]
max_apples_total = 14
options_per_day = 2
# Define model and solver
model = ConcreteModel()
solver = SolverFactory('gurobi') # Can use gurobi or glpk
# Define variables
model.DAYS = range(len(daily_price_offer))
model.OPTIONS = range(options_per_day)
model.x = Var(model.DAYS, model.OPTIONS, within=Binary)
# Constraint functions
def daily_sale_constraint(model, i):
"limited to 1 option in a given day"
return sum(model.x[i,:]) <= 1
# Set constraints
model.weight = Constraint(expr = sum(daily_price_offer[i][j][0] * model.x[i,j] for i in model.DAYS for j in range(options_per_day)) <= max_apples_total)
model.discharge = Constraint(model.DAYS, rule=daily_sale_constraint)
# Set objective
model.value = Objective(expr = sum(daily_price_offer[i][j][1] * daily_price_offer[i][j][0] * model.x[i,j] for i in model.DAYS for j in range(options_per_day)), sense = maximize)
# Solve
res = solver.solve(model)
# Print results
print('Chosen bundle:',[value(model.x[i,j]) for i in model.DAYS for j in range(options_per_day)])
print('Total revenue: $',model.value())