Optimization 不返回最优值的背包算法

Optimization 不返回最优值的背包算法,optimization,python-2.7,combinatorics,knapsack-problem,Optimization,Python 2.7,Combinatorics,Knapsack Problem,我正试图用python编写一个背包问题的算法。我进行了多次迭代,得出了以下解决方案。对我来说似乎很完美。当我在测试集上运行它时 它不会输出最佳值 有时给出最大递归深度误差 更改maxValues函数后,它将输出最佳值,但对于具有更多点的数据集,这需要很长时间。如何提炼 对于第二个问题,我检查了它给出错误的数据。数据非常庞大,只有两个数据超过了背包的容量。因此,它不必要地贯穿整个列表 因此,我计划做的是在运行递归函数的开始,我尝试查看整个权重列表,其中每个权重都小于当前容量,并删除其余的权重。

我正试图用python编写一个背包问题的算法。我进行了多次迭代,得出了以下解决方案。对我来说似乎很完美。当我在测试集上运行它时

  • 它不会输出最佳值
  • 有时给出最大递归深度误差
更改maxValues函数后,它将输出最佳值,但对于具有更多点的数据集,这需要很长时间。如何提炼

对于第二个问题,我检查了它给出错误的数据。数据非常庞大,只有两个数据超过了背包的容量。因此,它不必要地贯穿整个列表

因此,我计划做的是在运行递归函数的开始,我尝试查看整个权重列表,其中每个权重都小于当前容量,并删除其余的权重。下面是我计划实现的代码

#~ weights_jump = find_indices(temp_w, lambda e: e < capacity)
#~ if(len(weights_jump)>0):
#~ temp_w[0:weights_jump[0]-1] = [] 
#~ temp_v[0:weights_jump[0]-1] = [] 
下面是递归函数

def maxValues(weights,values,K):
weights = weights;
values = values;
a=[];
l = 0;
#~ print('hello');
items = len(weights);
#~ print(items);
max = 0;k = K;
for i in range(0,items):
    t = (i,float(values[i])/weights[i]);
    a.append(t);
    #~ print(i);

a = sorted(a,key=operator.itemgetter(1),reverse=True);
#~ print(a);
length = len(a);
for (i,v) in a:
    #~ print('this is loop'+str(l)+'and k is '+str(k)+'weight is '+str(weights[i]) );
    if weights[i]<=k:
        max = max+values[i];
        w = weights[i];
        #~ print('this'+str(w));
        k = k-w;
        if(k==0):
            break;
    else:
        max = max+ (float(k)/weights[i])*values[i];
        w = k
        k = k-w;
        #~ print('this is w '+str(max));
        if(k==0):
            break;


    l= l+1;




return max;
我将尝试解释这个递归函数。假设我从根节点开始,现在我有两个决定,要么选择第一个元素,要么不选择

在此之前,我将调用maxValue函数,以查看在此分支之后可以获得的最大值。如果它小于现有的_max,则无需搜索,因此修剪

如果第一个元素的重量小于容量,我将跟随左分支。因此
追加(1)
。 更新值、权重列表等,然后再次调用
节点
函数

所以它首先横穿整个左分支,然后横穿右分支

在右边,我只是更新值、权重列表和调用节点函数

对于该功能,输入为

  • value——问题的当前值,它最初设置为零,然后它变大
  • 重量表
  • 值列表
  • 电流容量
  • algo找到的当前最大值。如果该现有_max大于通过分支可获得的最大值, 没有必要搜索该分支。所以整个树枝都被剪掉了
  • existing_nodes是一个列表,它告诉您是否获取了特定项(1)(0)

  • 我花了好几天时间在这上面,什么也做不了。

    众所周知,贪婪算法通常不会使背包的价值最大化。你知道的,对吧?这是一个贪婪的算法吗?已经很晚了,我并没有完全遵循这段代码。贪婪算法在solveIt()的注释中提到,贪婪算法通常会挑选每单位重量价值最高的物品,直到背包装满为止。maxValue()似乎正在做这些事情你知道吗?如果你把背包说成是服从整数不等式的最大化,那么lp_solve将解决背包问题?我在生产中使用过lpsolve,这是一个更早的版本,当时它是一个独立的C程序。它可以工作,现在似乎有很多不同语言的API。如果目标是得到答案,我会试试看。如果目标是写一个算法,比如说为类,它不会这样做。哦,注释在那里,因为我从一个贪婪的算法开始,然后来到这个版本。很抱歉,我没有删除评论。这个算法是用来提交作业的。
    def node(value,weights,values,capacity,existing_max,existing_nodes):
    v1=[];e1=[]; #values we get from left branch
    v2=[];e2=[]; #values we get from right branch
    e=[];           
    e = existing_nodes[:];
    temp_w = weights[:]
    temp_v = values[:];
    
    #first check if the list is empty
    if(len(values)==0):
    
        r = [value,existing_nodes[:]]
        return r;
    
    
    
    #centre  check if this entire branch could be pruned. it checks for max value that can be obtained is more than the max value inputted to this 
    max_value = value+maxValue(weights,values,capacity);
    print('existing _max is '+str(existing_max))
    print('weight in concern '+str(weights[0])+' value is '+str(value))
    if(max_value<=existing_max):
        return [0,[]];
    
    
    
    #Transversing the left branch
    
    #Transverse only if the weight does not exceed the capacity
    print colored('leftbranch','red');
    #search for indices of weights where weight < capacity
    #~ weights_jump = find_indices(temp_w, lambda e: e < capacity)
    #~ if(len(weights_jump)>0):
        #~ temp_w[0:weights_jump[0]-1] = [] 
        #~ temp_v[0:weights_jump[0]-1] = [] 
    
    if(temp_w[0]<=capacity):
        updated_value = temp_v[0]+value;
        k = capacity-temp_w[0];
        temp_w.pop(0);
        temp_v.pop(0);
        e1 =e[:]
        e1.append(1);
        print(str(updated_value)+' '+str(k)+' ')
        raw_input('press ')
        v1=  node(updated_value,temp_w,temp_v,k,existing_max,e1);
        #after transversing left node update existing_max
        if(v1[0]>existing_max):
            existing_max = v1[0];
    else:
        v1 = [0,[]] 
    
    
    
    
    
    #Transverse the right branch 
    #it implies we are not including the current value so remove that from weights and values.
    print('rightbranch')
    #~ print(str(value)+' '+str(capacity)+' ')
    raw_input("Press Enter to continue...")
    weights.pop(0);
    values.pop(0);  
    e2 =e[:];  
    e2.append(0);
    v2 = node(value,weights,values,capacity,existing_max,e2);   
    
    if(v1[0]>v2[0]):
        return v1;
    else:
        return v2;  
    
    def maxValues(weights,values,K):
    weights = weights;
    values = values;
    a=[];
    l = 0;
    #~ print('hello');
    items = len(weights);
    #~ print(items);
    max = 0;k = K;
    for i in range(0,items):
        t = (i,float(values[i])/weights[i]);
        a.append(t);
        #~ print(i);
    
    a = sorted(a,key=operator.itemgetter(1),reverse=True);
    #~ print(a);
    length = len(a);
    for (i,v) in a:
        #~ print('this is loop'+str(l)+'and k is '+str(k)+'weight is '+str(weights[i]) );
        if weights[i]<=k:
            max = max+values[i];
            w = weights[i];
            #~ print('this'+str(w));
            k = k-w;
            if(k==0):
                break;
        else:
            max = max+ (float(k)/weights[i])*values[i];
            w = k
            k = k-w;
            #~ print('this is w '+str(max));
            if(k==0):
                break;
    
    
        l= l+1;
    
    
    
    
    return max;