so I have a list of stores and their inventory and a shopping list. I need to find the minimum number of stores to satisfy the shopping list. I currently have separated the store name to create all permutations of the stores. I am not sure how to actually make the comparison of stores inventory to the shopping list I have. Any help would be greatly appreciated.
def satisfy_shopping_list(shopping_list_json, inventory_json):
# find out minimum combination of stores that would satisfy shopping list
shops = []
print(inventory_json['stores'])
for item in inventory_json['stores']:
shops.append(item.get("name"))
routes = list(itertools.permutations(shops))
print(routes)
# if shopping list is impossible to satisfy
shopping_list_satisfiable = True
if shopping_list_satisfiable:
# print out number of stores and corresponding combinations
# num_stores = 0
# print "The shopping list can be satisfied by visiting {} store(s):".format(num_stores)
# for each valid store_combination:
# print_store_list(store_combination)
pass
else:
print("No combination of given stores can satisfy this shopping list :(")
pass
def print_store_combination(store_combination):
store_combination_copy = copy.deepcopy(store_combination)
store_combination_copy.sort()
print(', '.join(store_combination_copy))
def main():
args = parse_args()
with open(args.shopping_list_json_path) as shopping_list_json_file, open(args.inventory_json_path) as inventory_json_file:
shopping_list_json = json.load(shopping_list_json_file)
inventory_json = json.load(inventory_json_file)
satisfy_shopping_list(shopping_list_json, inventory_json)
def parse_args():
p = argparse.ArgumentParser()
p.add_argument('shopping_list_json_path')
p.add_argument('inventory_json_path')
args = p.parse_args()
return args
if __name__ == '__main__':
main()
Example Shopping List
{
"apples": 10,
"oranges": 10,
"pineapples": 10,
"coconuts": 10,
"strawberries": 10,
"peaches": 1
}
Inventory Example
{
"stores": [
{
"name":"Kroger",
"inventory": {
"oranges": 10,
"coconuts": 10,
"strawberries": 10
}
},
{
"name":"Meijer",
"inventory": {
"oranges": 10,
"grapes": 10,
"pineapples": 10,
"strawberries": 10
}
},
{
"name":"Store 3",
"inventory": {
"apples": 1,
"oranges": 10,
"bananas": 10,
"grapes": 10,
"chickens": 10
}
},
{
"name":"Whole Foods",
"inventory": {
"grapes": 10,
"pineapples": 10,
"organic apples": 10,
"coconuts": 10,
"strawberries": 10
}
},
{
"name":"Kroger 2",
"inventory": {
"apples": 8
}
},
{
"name":"peach store",
"inventory": {
"peaches": 1
}
},
{
"name":"CVS",
"inventory": {}
},
{
"name":"apples r us",
"inventory": {
"apples": 10000000000000
}
}
]
}
Here's a rough solution from me - just by prioritizing shops that are able to satisfy your shopping list most. Then you just iterate and trim the shopping list from there. I'm leaving the satisfiability check of the shopping list to you. You should do the check before jumping into the iteration I believe, by comparing the aggregate of the inventory against the numbers required in the shopping list.
def satisfy_shopping_list(shopping_list_json, inventory_json):
# find out minimum combination of stores that would satisfy shopping list
shops = []
inventory = [] # De-nesting the shops and their inventories. Matched by index
for item in inventory_json['stores']:
shops.append(item.get("name"))
inventory.append(item.get("inventory"))
# if shopping list is impossible to satisfy
shopping_list_satisfiable = True # You need to do this check yourself
shop_seq = []
if shopping_list_satisfiable:
while len(shopping_list_json) > 0:
# Compute satisfiability score for all shops
# We assign a score of 1 for each item that the shop is able to satisfy fully
# Else, we give it a pro-rated score if the shop has the supplies
scorelist = []
for i, ivt in enumerate(inventory):
score= 0
for k, v in shopping_list_json.items():
if k in ivt.keys():
if ivt[k] >= v:
score += 1
else:
score += (ivt[k]/v)
scorelist.append((score, i))
# Go to the shop with the highest score first
scorelist.sort(key=itemgetter(0), reverse=True)
shop_seq.append(shops[scorelist[0][1]])
# Update shopping list
shop_idx = scorelist[0][1]
to_remove = []
for k, v in shopping_list_json.items():
if k in inventory[shop_idx].keys():
if v - inventory[shop_idx][k] <= 0:
to_remove.append(k)
else:
shopping_list_json[k] = v - inventory[shop_idx][k]
for rem in to_remove:
shopping_list_json.pop(rem)
print(shop_seq)
else:
print("No combination of given stores can satisfy this shopping list :(")
pass
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.