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

时间:2018-10-05 20:20:26

标签: python knapsack-problem

我正在尝试使用Python解决背包问题,实现贪婪算法。我回来的结果对我来说毫无意义。

背包:

第一行给出了项目的数量,在这种情况下为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代码:

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)

结果:

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

2 个答案:

答案 0 :(得分:1)

欢迎。您的程序权重超过上限的原因是因为您要放入背包中的最后一件物品,而不是在检查它是否适合。为此,只需添加一个if语句,还应检查值列表是否为空。请注意,由于您的文本文件的索引从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

答案 1 :(得分:0)

问题是-在最后一步-您找到的最好的物品将超过最大重量。但是,由于您已经进入循环,因此无论如何都要添加它。 在下一次迭代中,您将认识到自己已超出上限并停下来。

我不确定一旦下一个最佳选择太重了,您想如何继续。如果您只是想停止而不添加其他内容,则可以简单地将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