Cod sursa(job #2519788)

Utilizator adeenacheAdelina Enache adeenache Data 8 ianuarie 2020 13:54:56
Problema Problema rucsacului Scor 0
Compilator py Status done
Runda Arhiva educationala Marime 3.84 kb
# ## read the cost matrix 
# import heapq
# with open('date.in', 'r') as f:
#     c = [[ int(num) if (num != 'inf') else float('inf') for num in line.split(' ')] for line in f]
# print(c)


# class Node: 
#     def __init__(): 


# def row_reduction(matrix, reduction):
#     copy = []
#     for index, row in enumerate(matrix):
#         minElem = min(row)
#         reduction[index] += minElem
#         print ('min elem', minElem, row)
#         copy.append([e-minElem for e in row])
#     return copy


# def column_reduction(matrix, reduction): 
#     copy = []
#     tc = list(zip(*matrix))
#     for index, row in enumerate(tc):
#         print ("have row", row)
#         minElem = min(row)
#         reduction[index] += minElem
#         copy.append([e-minElem for e in row])
#     return list(zip(*copy))



# def get_lower_bound(matrix): 
#     cost = 0

#     rows = [0] * len(c)
#     columns = [0] * len(c[0])

#     rr_matrix = row_reduction(matrix, rows)
#     print (rr_matrix)
#     r_matrix = column_reduction(rr_matrix, columns)

#     print ("rows, columns", rows, columns)
#     return r_matrix
    
# # print(row_reduction(c,rows), rows)
# print (get_lower_bound(c))

# def travel(): 



# input data 
# N, Gmax
# value1, weight1 
# ...
# valueN, weightN 

import heapq
class PriorityQueue:
    def __init__(self):
        self._queue = []
        self._index = 0

    def push(self, item, priority):
        heapq.heappush(self._queue, (-priority, self._index, item))
        self._index += 1

    def pop(self):
        return heapq.heappop(self._queue)[-1]
    
    def empty(self):
        if (len(self._queue) is 0):
            return True
        else:
            return False

    def length(self):
        return len(self._queue)

class Item: 
    def __init__(self, weight, value): 
        self.weight = weight
        self.value = value
        self.bound = bound 
        self.level = 0


class Node: 
    def __init__(self, value = 0, weight = 0, bound = 0, level = -1): 
        self.value = value
        self.weight = weight
        self.bound = bound
        self.level = level

    def create_from_prev(self, previous_node, item):
        self.value = previous_node.value + item.value
        self.weight = previous_node.weight + item.weight
        self.level = previous_node.level + 1



def bound(node, capacity, items): 
    if (node.weight > capacity): 
        return 0
    
    result = node.value
    weight = node.weight

    for item in items[node.level + 1:]: 
        if (item.weight + weight <= capacity):
            result += item.value

    return result

def knapsack(data, capacity): 
    items = sorted(data, key = lambda i: i.weight/i.value)

    start_node = Node(0, 0)
    start_node.bound = bound(start_node, G, items)

    Q = PriorityQueue()
    Q.push(start_node, start_node.bound)


    maxValue = 0
    solution = []

    while not Q.empty(): 
        node = Q.pop()

        if (node.bound > maxValue): 
            next_node = Node()
            next_node.create_from_prev(node, items[node.level + 1])

            if (next_node.weight <= capacity and next_node.value > maxValue): 
                maxValue = next_node.value
            
            next_node.bound = bound(node, capacity, items)


            if (next_node.bound > maxValue): 
                Q.push(next_node, next_node.bound)


            next_node2 = Node(node.value, node.weight, 0, node.level + 1)
            next_node2.bound = bound(node, capacity, items)

            if (next_node2.bound > maxValue): 
                Q.push(next_node2, next_node2.bound)
    
    return maxValue



with open('date.in', 'r') as f:
    # weight, value

    lines = f.readlines()
    global n 
    n = int(lines[0].split(' ')[0])
    global G
    G  = int(lines[0].split(' ')[1])
    data = [Item(int(line.split(' ')[0]), int(line.split(' ')[1])) for line in lines[1:]]

print (knapsack(data, G))