简体   繁体   English

试图找到贪婪背包问题的最佳子集(python)

[英]Trying to find the optimal subset for the Greedy knapsack problem(python)

I think this is the correct algorithm for finding the optimal value, but now i need to find the optimal subsets that got me that value.我认为这是找到最佳值的正确算法,但现在我需要找到获得该值的最佳子集。 Help would be greatly appreciated!帮助将不胜感激!

These were my directions: Implement a greedy algorithm that arranges the items in the decreasing order of value to weight ratio (vi/wi for i = 1, 2, ..., n), then select the items in this order until the weight of the next item exceeds the remaining capacity (Note: In this greedy version, we stop right after the first item whose inclusion would exceed the knapsack capacity).这些是我的方向:实现一个贪心算法,按价值与重量比的降序排列项目(vi/wi for i = 1, 2, ..., n),然后 select 按此顺序排列项目,直到重量下一个项目超过剩余容量(注意:在这个贪婪版本中,我们在第一个包含超过背包容量的项目之后立即停止)。

def greedy_knapsack(val, weight, W, n):
    # index = [0, 1, 2, ..., n - 1] for n items
    index = list(range(len(val)))
    # contains ratios of values to weight
    ratio = [v / w for v, w in zip(val, weight)]
    QuickSort(ratio, 0, len(ratio) - 1)
    max_value = 0
    for i in index:
        if weight[i] <= W:
            max_value += val[i]
            W -= weight[i]
        else:
            max_value += val[i] * W // weight[i]
            break
    return max_value

Your greedy approach will fail in many cases.在许多情况下,你的贪婪方法会失败。

One such trivial case:一个这样的微不足道的案例:

weight = [10, 10, 10]
value = [5, 4, 3]
W = 7

In this case, your algorithm will choose (item 1) sum = 5, but the optimal answer should be (items 2 and 3), sum = 7.在这种情况下,您的算法将选择 (项目 1) sum = 5,但最佳答案应该是 (项目 2 和 3),总和 = 7。

You need a dynamic programming approach to solve this and you can keep a matrix to store your previous states so that you can reconstruct the solution and get the item list.您需要一种动态编程方法来解决这个问题,并且您可以保留一个矩阵来存储您以前的状态,以便您可以重建解决方案并获取项目列表。

# Prints the items which are put in a  
# knapsack of capacity W 
def printknapSack(W, wt, val, n): 
    K = [[0 for w in range(W + 1)] 
            for i in range(n + 1)] 

    # Build table K[][] in bottom 
    # up manner 
    for i in range(n + 1): 
        for w in range(W + 1): 
            if i == 0 or w == 0: 
                K[i][w] = 0
            elif wt[i - 1] <= w: 
                K[i][w] = max(val[i - 1]  
                  + K[i - 1][w - wt[i - 1]], 
                               K[i - 1][w]) 
            else: 
                K[i][w] = K[i - 1][w] 

    # stores the result of Knapsack 
    res = K[n][W] 
    print(res) 

    w = W 
    for i in range(n, 0, -1): 
        if res <= 0: 
            break
        # either the result comes from the 
        # top (K[i-1][w]) or from (val[i-1] 
        # + K[i-1] [w-wt[i-1]]) as in Knapsack 
        # table. If it comes from the latter 
        # one/ it means the item is included. 
        if res == K[i - 1][w]: 
            continue
        else: 

            # This item is included. 
            print(wt[i - 1]) 

            # Since this weight is included 
            # its value is deducted 
            res = res - val[i - 1] 
            w = w - wt[i - 1] 

# Driver code 
val = [ 60, 100, 120 ] 
wt = [ 10, 20, 30 ] 
W = 50
n = len(val) 

printknapSack(W, wt, val, n) 

ref: https://www.geeksforgeeks.org/printing-items-01-knapsack/参考: https://www.geeksforgeeks.org/printing-items-01-knapsack/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM