如何找到最小商店数?

时间:2019-05-09 01:19:19

标签: python python-3.x

所以我有一个商店清单及其库存和一个购物清单。我需要找到能够满足购物清单的最小商店数量。我目前已经分离出商店名称以创建商店的所有排列。我不确定如何实际比较商店库存和我的购物清单。任何帮助将不胜感激。

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()

购物清单示例

{
    "apples": 10,
    "oranges": 10,
    "pineapples": 10,
    "coconuts": 10,
    "strawberries": 10,
    "peaches": 1
}

库存示例

{
    "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
            }
        }
    ]
}

1 个答案:

答案 0 :(得分:0)

这是我的一个粗略解决方案-仅通过优先选择最能满足您的购物清单的商店。然后,您只需从那里迭代并修剪购物清单即可。我把购物清单的满意度检查留给您。您应该在进入我认为的迭代之前进行检查,方法是将库存总量与购物清单中所需的数量进行比较。

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