贪婪算法解决背包问题

时间:2022-03-16 04:20:39

题目:有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大


现在假设我们有七个物品,它们的重量为 35,30,60,50,40,10,25,价值分别为 10,40,30,50,35,40,30,背包的重大承重为150,装入一个或多个使其价值最大且不超过所能承受的重量?

思路1: 简单的贪婪  1)从剩余的物品中拿出价值最大并且状态为可以放置的物品(默认都是可以放置)
                               2) 检查包中是否还能容纳该物品的重量,如果能加放入包内,并且把该物品状态置为已放        置。如果重量超过包内还能容纳的重量则置物品状态为不能放置。
                               3) 重复以是步骤直到找不到可以放置的物品
代码:
先来一个表示物品信息类:
class Product(object):
    weight = 0
    values = 0
    status = 0

    def __init__(self, w, v, s):
        super(Product, self).__init__()
        self.weight = w
        self.values = v
        self.status = s

从物品中选出价值最大的 (状态0表示可放置, 1 表不已放置, 2表示不可放置)
def choose_by_price(objects):
    index = -1
    mp = 0
    for j in range(0, len(objects)):
        ob = objects[j]
        if ob.status == 0 and mp < ob.values:
            mp = ob.values
            index = j
    return index

解决背包问题:
def solve_package(objects, max_weight):
    choose_products = []
    total_weight = 0
    #1)从剩余的物品中拿出价值最大并且状态为可以放置的物品
    index = choose_by_price(objects)
    choose_one = objects[index]
    while index != -1:
        print("index = %d" % index)
        # 2)检查包中是否还能容纳该物品的重量,如果能加放入包内,并且把该物品状态置为已放      					  置
        if objects[index].weight <= max_weight - total_weight:
            print('weight = %d'% choose_one.weight)
            objects[index].status = 1
            choose_products.append(objects[index])
            total_weight += objects[index].weight
        #2)如果重量超过包内还能容纳的重量则置物品状态为不能放置
        else:
            objects[index].status = 2
        #3) 重复以是步骤直到找不到可以放置的物品    
        index = choose_by_price(objects)

    for product_one in choose_products:
        print("%d\n" % product_one.weight)

经过上面的步骤我们能得到一个数值,但可能不是最优的,因为他只是简单的贪婪,还会有其它的方法比较更好的贪婪法来获取最优值。

如果我们以重量跟价值的比作为比较的标准情况会更好些,把上面的代码改一下:
__author__ = 'barryclass'


class Product(object):
    status = 0

    def __init__(self, value, weight, sta):
        super(Product, self).__init__()
        self.value_weight = value / weight
        self.value = value
        self.weight = weight
        self.status = sta


def get_best_value_weight(products, weight):
    have = False
    choose = 0
    for i in range(0, len(products)):
        if products[i].status == 0 and products[i].value_weight >= products[choose].value_weight:
            print('come here')
            have = True
            choose = i
    if have:
        return choose
    return None


def solve_greedy_algorithm(products, weight):
    left_weight = weight
    result = []
    index = get_best_value_weight(products, left_weight)
    print(index)
    while index is not None:
        if products[index].weight <= left_weight:
            result.append(products[index])
            products[index].status = 1
            left_weight -= products[index].weight
        else:
            products[index].status = 2
        index = get_best_value_weight(products, left_weight)
    return result


if __name__ == '__main__':
    weights = [35.0, 30.0, 60.0, 50.0, 40.0, 10.0, 25.0]
    value = [10, 40, 30, 50, 35, 40, 30]
    products = []
    for i in range(0, len(weights)):
        product = Product(value[i], weights[i], 0)
        products.append(product)
    res = solve_greedy_algorithm(products, 150)

    for product in res:
        print(product.weight)

 如果我们选择以价值最大来贪婪,获得物品重量 为50,10,30,40  其最大重量为 130 ,价值为  50, 40,40, 35   总价值为 165
如果是以价值重量比来贪婪, 获取物品重量为 10.0 30.0 25.0 50.0 35.0 价值为40 40 30 50 10   总价值为170