在python中通过bruteforce解决背包方法

时间:2016-09-28 09:55:09

标签: python brute-force knapsack-problem

我实际上试图通过强力解决背包问题。我知道它根本没有效率,我只想在python中实现它。

问题是需要很长时间。在我看来,有太多时间进行暴力破解。所以也许我在代码中犯了一些错误......

def solve_it(input_data):
# Start the counting clock
start_time = time.time()

# Parse the input
lines = input_data.split('\n')
firstLine = lines[0].split()
item_count = int(firstLine[0])
capacity = int(firstLine[1])

items = []

for i in range(1, item_count+1):
    line = lines[i]
    parts = line.split()
    items.append(Item(i-1, int(parts[0]), int(parts[1])))

# a trivial greedy algorithm for filling the knapsack
# it takes items in-order until the knapsack is full
value = 0
weight = 0
best_value = 0

my_list_combinations = list()
our_range = 2 ** (item_count)

print(our_range)

output = ""

for i in range(our_range):
    # for exemple if item_count is 7 then 2 in binary is
    # 0000010
    binary = binary_repr(i, width=item_count)

    # print the value every 0.25%
    if (i % (our_range/400) == 0):
        print("i : " + str(i) + '/' + str(our_range) + ' ' +
            str((i * 100.0) / our_range) + '%')
        elapsed_time_secs = time.time() - start_time
        print "Execution: %s secs" % \
            timedelta(seconds=round(elapsed_time_secs))

    my_list_combinations = (tuple(binary))

    sum_weight = 0
    sum_value = 0

    for item in items:
        sum_weight += int(my_list_combinations[item.index]) * \
            int(item.weight)

    if sum_weight <= capacity:
        for item in items:
            sum_value += int(my_list_combinations[item.index]) * \
                int(item.value)

        if sum_value > best_value:
            best_value = sum_value
            output = 'The decision variable is : ' + \
                str(my_list_combinations) + \
                ' with a total value of : ' + str(sum_value) + \
                ' for a weight of : ' + str(sum_weight) + '\n'
return output

这是包含30个对象的文件:

30 100000 # 30 objects with a maximum weight of 100000
90000 90001
89750 89751
10001 10002
89500 89501
10252 10254
89250 89251
10503 10506
89000 89001
10754 10758
88750 88751
11005 11010
88500 88501
11256 11262
88250 88251
11507 11514
88000 88001
11758 11766
87750 87751
12009 12018
87500 87501
12260 12270
87250 87251
12511 12522
87000 87001
12762 12774
86750 86751
13013 13026
86500 86501
13264 13278
86250 86251

我没有显示相对于文件读取的代码,因为我认为它毫无意义......对于19个对象,我能够在14秒内用强力解决问题。但对于30个物体,我已经计算出它需要大约15小时。所以我认为我的计算存在问题......

任何帮助将不胜感激:)

ASTRUS

1 个答案:

答案 0 :(得分:0)

解决背包问题需要太长时间的问题确实令人沮丧,并且它会出现在算法是高阶多项式或非多项式的其他地方。您正在看到算法具有指数运行时意味着什么;)换句话说,无论您的python代码是否有效,您都可以非常轻松地构建您的计算机无法解决的背包问题的版本在你的一生中。

指数运行时间意味着每次将另一个对象添加到列表中时,暴力解决方案将花费两倍的时间。如果你可以在14秒内解决19个物体,那表明30个物体需要14秒x(2 ** 11)= 28672秒=约8小时。要做31个对象可能需要大约16个小时。等

有背包问题的动态编程方法,它牺牲了内存的运行时间(see the Wikipedia page),并且有一些数值优化器可以很快地解决基于约束的问题(again, Wikipedia),但是这一切都没有真正改变这样一个事实,即找到背包问题的确切解决方案是非常困难的。

TL; DR:您可以在合理的时间内解决19个对象,但不能解决30个(或100个对象)。这是您正在解决的问题的属性,而不是Python代码的缺点。