The description of the Gift Problem does not state whether Ahmad can pack a single item multiple times into his backpack. I assume that this is allowed, but still give solution for both cases.
I estimated the item volumes with least square method.
Volume Estimations with Least Square Method
A1: 22.021118524229237; A2: 14.45781057459718; A3: 8.454916764907193; A4: 23.950558756832113; A5: 16.608708443894614; A6: 0.37567656740091904; A7: 8.83333202950414; A8: 3.5461802660479966; A9: 0.9593400482423037; A10: 14.540566462507497; A11: 22.77823394134002; A12: 14.964040774318565; A13: 21.54299887703683; A14: 29.669818032304043; A15: 11.036597705506871; A16: 15.957820495491042; A17: 6.864389014170886; A18: 8.352695353244146; A19: 15.184085730433905; A20: 22.104818560228278; A21: 26.435365285293734; A22: 25.803030807701752; A23: 7.27123906961052; A24: 25.775826640735204; A25: 9.482042023006557; A26: 20.583395403232; A27: 7.515408134789879; A28: 6.832125304629022; A29: 20.850502769938625; A30: 19.326638574705974; A31: 6.875682589926919; A32: 0.9218247852384645; A33: 5.946422038616392; A34: 13.246743951714274; A35: 4.975683341427916; A36: 25.11605272089536; A37: 12.500112589023555; A38: 9.898305182537658; A39: 1.5554143168213463; A40: 10.532179324218948; A41: 23.033278454756104; A42: 11.566374135419498; A43: 5.005751745097541; A44: 4.8114853019376795; A45: 22.43858887689611; A46: 17.58217751885109; A47: 26.037340206750926; A48: 7.212602587589086; A49: 11.176684062545817; A50: 11.384898741525287; A51: 26.99512694944281; A52: 23.010644144875265; A53: 5.623208376885822; A54: 11.655422808835144; A55: 16.508915373108138; A56: 10.441519525942489; A57: 18.70332938563313; A58: 25.492607324517877; A59: 16.193789972373573; A60: 12.35544498375213Ahmad should pack items A6, A8, A9, A23, A32, A35, A38, A44, A48. This yields a total price of 757.0 and a total estimated volume of 39.9723.
Ahmad should pack item A6 106 times. This yields a total price of 11554.0 and a total estimated volume of 39.8217.
To run this software, please install Python 3.12, gurobipy and qpsolvers,
and then run choose_gifts.py. By default, this solves the
problem and prints the chosen items, estimated total backpack volume and the
total cost.
My solution for the Gift Problem consists of two steps:
- Estimating item volumes by minimizing error / deviation
- Solving deterministic knapsack model with estimated item volumes and potentially with multiple packing of single item allowed.
There is no information about outlier in the measured total package volumes, therefore I propose to estimate the package volumes by two methods. One of the methods is less prone to be influenced by outliers.
Let
For each item
For each package
The Least Square Problem consists of finding an assignment of all
A solution gives a reasonably well volume estimation under the assumption that the error follows a normal distribution, has a constant variance and there are not too many outliers. The former applies, the latter is unknown. On a theoretical note, this works because maximum likelihood estimation of a normal distributed error is the least square estimation.
I use qpsolvers to model the Least Square Problem as a QP and solve it with a QP solver.
For source code, see regression/ls.py.
Most of the formulation of the Least Square method applies to Least Absolute
Deviation Problem. Instead of minimizing the squared deviation, we instead minimize the
absolute deviation:
I express the formulation of the Least Absolute Deviation Problem as a linear program.
I introduce non-negative continuous variables
This yields an LP that can be solved by any off-the-shelf LP solver
I use Gurobi and gurobipy to solve the construced LP and therefore to solve the Least Absolute Deviation Problem.
For source code, see regression/lad.py.
Optimally packing Ahmad's backpack without exceeding the capacity and maximizing profit / item cost is a Knapsack problem.
Given estimated item volumes
I introduce a non-negative integer variable
In total, this model is a Mixed-Integer Linear Program and is solved with B&C.
I use gurobipy and Gurobi for expressing and solving this MILP. For source code, see knapsack.py.
qpsolvers acts as a generic interface for quadratic programming solvers. It offers an abstraction that solves Least Square by transforming the LS problem into a QP. It then calls an underlying QP solver.
I use Gurobi and gurobipy ...
- for solving the knapsack model
- as the underlying QP solver for
qpsolvers' LS solver - for solving Least Absolute Deviation as an LP