-1

I'm trying to solve the Knapsack problem with the dynamical programming(DP) approach, with Python 3.x. My TA pointed us towards this code for a head start. I've tried to implement it, as below:

def take_input(infile):
    f_open = open(infile, 'r')
    lines = []
    for line in f_open:
        lines.append(line.strip())
    f_open.close()
    return lines

def create_list(jewel_lines):
    #turns the jewels into a list of lists
    jewels_list = []
    for x in jewel_lines:
        weight = x.split()[0]
        value = x.split()[1]
        jewels_list.append((int(value), int(weight)))
    jewels_list = sorted(jewels_list, key = lambda x : (-x[0], x[1]))
    return jewels_list

def dynamic_grab(items, max_weight):
    table = [[0 for weight in range(max_weight+1)] for j in range(len(items)+1)]

    for j in range(1,len(items)+1):
        val= items[j-1][0]
        wt= items[j-1][1]
        for weight in range(1, max_weight+1):
            if wt > weight:
                table[j][weight] = table[j-1][weight]
            else:
                table[j][weight] = max(table[j-1][weight],table[j-1][weight-wt] + val)

    result = []
    weight = max_weight
    for j in range(len(items),0,-1):
        was_added = table[j][weight] != table[j-1][weight]

        if was_added:
            val = items[j-1][0]
            wt = items[j-1][1]
            result.append(items[j-1])
            weight -= wt

    return result

def totalvalue(comb):
    #total of a combo of items
    totwt = totval = 0
    for val, wt in comb:
        totwt += wt
        totval += val
    return (totval, -totwt) if totwt <= max_weight else (0,0)

#required setup of variables    
infile = "JT_test1.txt"
given_input = take_input(infile)
max_weight = int(given_input[0])
given_input.pop(0)
jewels_list = create_list(given_input)

#test lines
print(jewels_list)
print(greedy_grab(jewels_list, max_weight))
bagged = dynamic_grab(jewels_list, max_weight)
print(totalvalue(bagged))

The sample case is below. It is in the format line[0] = bag_max, line[1:] is in form(weight, value):

575
125 3000
50 100
500 6000
25 30

I'm confused as to the logic of this code in that it returns me a tuple and I'm not sure what the output tuple represents. I've been looking at this for a while and just don't understand what the code is pointing me at. Any help would be appreciated.

Leonardo.Z
  • 9,425
  • 3
  • 35
  • 38
idalsin
  • 546
  • 2
  • 9
  • 31

2 Answers2

1

I assume you are referring to the tuples returned by totalvalue and contained in the list returned by createlist. These tuples all contain two integers. The first of these two numbers is the value of the jewel, and the second is the weight if the jewel.

The final tuple returned by totalvalue represents the maximum possible value of jewels which could be chosen from the list of input jewels, without exceeding the maximum weight.

If you want the value of all jewels, you should find totalvalue(jewels_list). The current tuple is not the value of all jewels, but only the value of the jewels which fit within the maximum weight.

amiller27
  • 491
  • 5
  • 8
  • The create list function is one I wrote, so that one I understand- creates a list of lists of weight,value pairs. The tuple for total value I would like to transition into an actual total value, if that makes sense – idalsin Oct 25 '13 at 04:07
0

The output tuple represents total value and total weight for the final solution.

bagged is a list, which like this[[125,3000],[500,6000]]. function total value just add up everything.

xuanyue
  • 1,368
  • 1
  • 17
  • 36
  • If this is a case, that the output represents total value, am I screwed up somewhere in maximizing value? – idalsin Oct 25 '13 at 04:18