I must buy one of each product, but I can visit no more then n shops. Which n shops should I choose to spend the least amount of money? Products are not divisible, every shop have full inventory.
| Shop A | Shop B | Shop C | |
|---|---|---|---|
| Product 1 | $10.00 | $12.00 | $9.99 |
| Product 2 | $8.50 | $9.99 | $7.99 |
| Product 3 | $15.00 | $14.50 | $16.99 |
So I need to minimize
df.min(axis=1).sum() , where df represents any combination of n columns.
The brute force algorithm would be:
import pandas as pd
from itertools import combinations
df = pd.DataFrame({'A': [1,3,4], 'B': [3,1,3], 'C': [2,3,1]})
best_so_far = df.iloc[:, 0]
n = 2
for combo in combinations(df.columns, n):
selection = df[list(combo)].min(axis=1)
if selection.sum() < best_so_far.sum():
best_so_far = selection
The goal is to improve time complexity. Using greedy approach, or dynamic programming doesn't work here, as there is no optimal subproblem. Sorting columns also doesn't help, because a shop (with half of its products prohibitively expensive and the other half almost free) can have a biggest total sum of its products, but still be the best candidate.
This code solves the problem. Sadly I am not interested in the output itself, but in complexity. How many steps should I do when trying to simulate underlying algorithm on paper?
The output:
Result - Optimal solution found
Objective value: 4.00000000
Enumerated nodes: 0
Total iterations: 0
Time (CPU seconds): 0.00
Time (Wallclock seconds): 0.00
Option for printingOptions changed from normal to all
Total time (CPU seconds): 0.00 (Wallclock seconds): 0.00
S_Store_1 = 0.0
S_Store_2 = 1.0
S_Store_3 = 1.0
X_('Store_1',_'Product_1') = 0.0
X_('Store_1',_'Product_2') = 0.0
X_('Store_1',_'Product_3') = 0.0
X_('Store_2',_'Product_1') = 0.0
X_('Store_2',_'Product_2') = 1.0
X_('Store_2',_'Product_3') = 0.0
X_('Store_3',_'Product_1') = 1.0
X_('Store_3',_'Product_2') = 0.0
X_('Store_3',_'Product_3') = 1.0
Total Cost = 4.0