简体   繁体   English

使用贪婪的python算法解决背包问题

[英]Solving knapsack problem using a greedy python algorithm

I'm trying to solve the knapsack problem using Python, implementing a greedy algorithm. 我正在尝试使用Python解决背包问题,实现贪婪算法。 The result I'm getting back makes no sense to me. 我回来的结果对我来说毫无意义。

Knapsack: 背包:

The first line gives the number of items, in this case 20. The last line gives the capacity of the knapsack, in this case 524. The remaining lines give the index, value and weight of each item. 第一行给出了项目的数量,在这种情况下为20。最后一行给出了背包的容量,在这种情况下为524。其余行给出了每个项目的索引,值和重量。

20
    1    91    29
    2    60    65
    3    61    71
    4     9    60
    5    79    45
    6    46    71
    7    19    22
    8    57    97
    9     8     6
   10    84    91
   11    20    57
   12    72    60
   13    32    49
   14    31    89
   15    28     2
   16    81    30
   17    55    90
   18    43    25
   19   100    82
   20    27    19
524

Python code: Python代码:

import os 

def constructive():     
    knapsack = []
    Weight = 0
    while(Weight <= cap):
        best = max(values)
        i = values.index(best)
        knapsack.append(i)
        Weight = Weight + weights[i]
        del values[i]
        del weights[i]
    return knapsack, Weight


def read_kfile(fname):
    with open(fname, 'rU') as kfile:
        lines = kfile.readlines()     # reads the whole file
    n = int(lines[0])
    c = int(lines[n+1])
    vs = []
    ws = []
    lines = lines[1:n+1]   # Removes the first and last line
    for l in lines:
        numbers = l.split()   # Converts the string into a list
        vs.append(int(numbers[1]))  # Appends value, need to convert to int
        ws.append(int(numbers[2]))  # Appends weigth, need to convert to int
    return n, c, vs, ws

dir_path = os.path.dirname(os.path.realpath(__file__))  # Get the directory where the file is located
os.chdir(dir_path)  # Change the working directory so we can read the file

knapfile = 'knap20.txt'
nitems, cap, values, weights = read_kfile(knapfile)
val1,val2 =constructive()
print ('knapsack',val1)
print('weight', val2)
print('cap', cap)

Result: 结果:

knapsack [18, 0, 8, 13, 3, 8, 1, 0, 3]
weight 570
cap 524

Welcome. 欢迎。 the reason why your program is giving a weights over the cap limit is because on the final item you are putting in the knapsack, you aren't checking if it can fit in it. 您的程序权重超过上限的原因是因为您要放入背包中的最后一件物品,而不是在检查它是否适合。 To do this just add an if statement, Also you should check if the list of values is empty. 为此,只需添加一个if语句,还应检查值列表是否为空。 Do note that I have append (i+1) since your text file's index is starting at 1 but Python starts it's list index at 0: 请注意,由于您的文本文件的索引从1开始,但是Python在0处开始了列表索引,因此我附加了(i + 1):

def constructive():
    knapsack = []
    Weight = 0

    while(Weight <= cap and values):
        best = max(values)
        i = values.index(best)
        if weights[i] <= cap-Weight:
            knapsack.append(i+1)
            Weight = Weight + weights[i]
        del values[i]
        del weights[i]

    return knapsack, Weight

The problem is -- in the last step -- the best item you find will exceed the maximum weight. 问题是-在最后一步-您找到的最好的物品将超过最大重量。 But since you already entered the loop you add it anyway. 但是,由于您已经进入循环,因此无论如何都要添加它。 In the next iteration you recognize that you are over the cap and stop. 在下一次迭代中,您将意识到自己已经超出上限并停止。

I am not sure how you want to proceed once the next best is too heavy. 我不确定一旦下一个最好的事情太重了,您想如何继续。 In case you simple want to stop and not add anything more you can simply modify your constructive to look as follows: 如果您只是想停止而不添加任何内容,则可以简单地将constructive修改为如下所示:

def constructive():

    knapsack = []
    Weight = 0

    while(True):
        best = max(values)
        i = values.index(best)

        if Weight + weights[i] > cap:
            break

        knapsack.append(i)
        Weight = Weight + weights[i]

        del values[i]
        del weights[i]

    return knapsack, Weight

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

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