Python中允许多个项目的简化0/1背包问题

2024-05-29 08:13:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个问题,是背包问题的简化版本。事情是这样的。有一个商店,我们有一个商店里的物品清单。这样说吧,, 本店有普通产品和限量产品两种产品

产品类别

class Product:
    """ 
    A class to provide abstraction for products availabel in the system.
    unless the product is a Limited_product its supply is infinite
    """
    product_counter = 0

    ##### Part 1.1 #####
    def __init__(self, name, price):
        """ Constructor for initialization """
        
        self.name = name
        self.price = price
        self.id = Product.product_counter
        Product.product_counter += 1

    def __str__(self):
        """ returns a string representation of a product """
        return "<{}> {} - {}$".format(self.id, self.name, self.price)

    def __repr__(self):
        """ represents the class object as a string """
        return "PRODUCT <{}>".format(self.id)

有限产品类别

class Limited_Product(Product):
    """
    A child class of the parent Product class
    Represents a Limited product where the quantity is depreceating
    """

    ##### Part 1.2 #####
    def __init__(self, name, price, amount):
        """ Constructor for initialization """
        super().__init__(name, price)
        self.amount = amount

    def __str__(self):
        """ returns a string representation of a limited product """
        return "<{}> {} - {}$ ({} left)".format(self.id, self.name, self.price, self.amount)

    def decrement_amount(self):
        """ decrement the amount of available product """
        self.amount -= 1

    def get_amount(self):
        """ returns the amount available from the product """
        return self.amount

现在我们得到了一份产品清单和客户可以消费的最高金额

================================================

产品价格

A-20美元

B-7美元

C-1美元(左二)

================================================

我们必须通过递归以及通过完成给定的两个函数来迭代,找出客户从这些项目中购买序列后的最小剩余量这些函数是给定的,因此我无法使用其他方法编写

例如:

>>> store.so_rich(45)

output - 1

你有45美元要花。最佳解决方案是购买六个B项目和两个C项目。这样你就剩下45-7*6-1*2=1美元了。剩下的钱最少是1,因为没有办法花光所有的钱。(虽然C的价格是1美元,但您已经购买了所有的产品!)

>>> store.so_rich(61)

0

你有61美元要花。你可以通过买两个A和三个B(20*2+7*3=61)来花掉所有的钱。所以剩下的钱最少是0

我编写的两个函数

    def so_rich(self, money):

        # suppose you haven't seen any product yet
        # the only possible amount of money left is "money"
        # this is a set to record the possible money left
        left = set([money])

        # get products
        lst = list(self.warehouse.inventory.values())
        print(str(lst))
        for product in lst:

            # a temporary set to save the updates of "left"
            # you don't want to modify the set you're iterating through
            tmp_left = set()

            for m in left:
                # update tmp_left
                if type(product) != Limited_Product:
                    new_left = m
                    #new_left -= product.price
                    while product.price <= new_left:
                        print(new_left, product.name)
                        tmp_left.add(new_left)
                        new_left = new_left - product.price
                else:
                    # handle limited product
                    new_left = m
                    product_count = product.amount
                    while product.price <= new_left and product_count > 0:
                        print(new_left, product.name)
                        tmp_left.add(new_left)
                        new_left = new_left - product.price
                        product_count -= 1
            left = tmp_left
            print(left)

        return min(left)

    def so_rich_recursive(self, money):

        # get products
        lst = list(self.warehouse.inventory.values())
        
        def helper(lst, money):
            
            # base case
            if not lst:
                return money
            
            cur_min = money
            product = lst[0]
            if type(product) != Limited_Product:
                tmp = money
                while product.price < tmp:
                    cur_min = tmp
                    tmp -= product.price
                    print(cur_min, product.name)
            else:
                tmp = money
                product_count = product.amount
                while product.price <= tmp and product_count > 0:
                    cur_min = tmp
                    tmp -= product.price
                    product_count -= 1
                    print(cur_min, product.name)
            money = money - cur_min
            print("-----", money)
            lst.pop(0)
            return helper(lst, money)
        
        return helper(lst, money)

我不明白为什么我写的上述代码不起作用。有人能帮我吗


Tags: thenameselfnewreturndefproductleft

热门问题