I wrote a small program to solve a problem i have but having trouble to scale it and could need some points/help.
There are 3 matrices for data
1) Price of an item
price = [
[11.5, 12.5, 10.75, 11.5],
[19, 13.5, 12.85, 11.9],
[1.95, 1.9, 1.75],
[2.95, 2.45, 1.65, 1.59],
[8.5, 6.45, 8.5, 8.5],
[12.5, 10.5, 10.25, 10.5],
[4.25, 5.5, 5.5, 5],
[4.25, 5.5, 5.5, 5],
[4.25, 5.5, 5.5, 5],
[50],
[30],
]
2) Difference nominal where 100 = best price
diff = [
[80, 86, 100, 80],
[47, 66, 93, 100],
[90, 92, 100],
[54, 65, 96, 100],
[100, 66, 100, 100],
[82, 98, 100, 81],
[97, 100, 88, 83],
[97, 100, 88, 83],
[97, 100, 88, 83],
[100],
[100]
]
3) Possible suppliers who can fully or partly deliver my products
data = [
[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2],
[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3],
[0],
[0],
]
Every supplier can have a constraint of min order and only one item per row.
deliverer = [0, 1, 2, 3]
min_order = {0: 50, 1: 30, 2: 0, 3: 100}
combinations = list(itertools.product(*data))
def compute(combinations):
def get_score(comb):
score = 0
available = []
for index, item in enumerate(comb):
score += diff[index][item]
available.append(diff[index][item])
return (score, all(i > 0 for i in available))
def get_price(comb):
price_dict = {key: {'price': 0, 'reached': False} for key in comb}
for index, item in enumerate(comb):
p = price[index][item]
price_dict[item]["price"] += p
if price_dict[item]["price"] >= min_order[item]:
price_dict[item]["reached"] = True
return price_dict
I then iterate over all possible combinations and calculate a score value and if the path taken from top to bottom can be delivered and contains all items.
new_comb = []
for comb in combinations:
score, all_items = get_score(comb)
price_dict = get_price(comb)
check = [value["reached"] for value in price_dict.values()]
can_deliver = False
if all(i is True for i in check):
can_deliver = True
if can_deliver is False:
continue
new_comb.append({"way": comb, "score": score, "all_items": all_items, "price": price_dict,
"can_deliver": can_deliver, "d_count": len(price_dict.keys())})
return new_comb
In this step i just sort my return values of my top solutions. Here i need to add another constrained to find the least amount of deliverer and step up till i have the maximum amount of deliverer who can deliver all items.
new_comb = compute(combinations)
new_comb = sorted(new_comb, key=lambda k: (k["can_deliver"], k["all_items"], k["score"]), reverse=True)
best_solutions = []
for item in new_comb:
if item["can_deliver"] is True:
best_solutions.append(item)
print(best_solutions[:15])
My problem is now how can i make this kind of problems scale. What techniques are viable to deal with a matrix for 60x10 or more.
I would appreciate any help.