zoukankan      html  css  js  c++  java
  • 0-1背包问题优化算法详解

    代码实现(python)

    #-*- coding:utf-8 -*-

    from copy import copy

    def add(p,x,c): #对应元素分别相加,p中每个元素都是元组,x也是一个元组

        resultlist=[(i[0]+x[0],i[1]+x[1]) for i in p if i[0]+x[0]<=c]

        return resultlist

    def union(p,q): #求并集,同时删除坏点

        pp=copy(p)

        qq=copy(q)

        delelement=[]

        for i in pp:

            for j in qq:

                if(i[0]>=j[0] and i[1]<=j[1]):

                    delelement.append(i)

                    break

                if(i[0]<=j[0] and i[1]>=j[1]):

                    delelement.append(j)

                    break

        for i in delelement:

            if i in pp:

                pp.remove(i)

            else:

                qq.remove(i)

        qq.extend(pp)

        qq.sort()

        return qq

    def package2(w,v,c,n):#动态规划主函数

        p=[[]]*(n+2)

        p[n+1]=[(0,0)]

        q= [[]] * (n + 2)

        for i in range(n+1,1,-1):

            q[i]=add(p[i],(w[i-2],v[i-2]),c)

            p[i-1] = union(p[i], q[i])

        return p,q

    def out(w,v,p,q,n):   #构造最优解

        maxpoint=p[1][-1]

        choose=[]

        for i in range(1,n+1):

            if((maxpoint in q[i+1]) and (maxpoint not in p[i+1])):

                choose.append(True)

                maxpoint=(maxpoint[0]-w[i-1],maxpoint[1]-v[i-1])

            else:

                choose.append(False)

        print 'max weight and value:', p[1][-1]

        print 'choose or not:', choose

    if __name__=='__main__':

        w=[2,2,6,5,4]

        v=[6,3,5,4,6]

        p,q=package2(w, v, 10, 5)

        out(w,v,p,q,5)

    结果输出:

    max weight and value: (8, 15)

    choose or not: [True, True, False, False, True]

    复杂度分析

    从之前的分析过程可以看出,每一个物品都存在选或者不选,如果没有删除坏点,

    则要计算的转折点个数为2^n个,即指数级的,但是正是因为中间过程删除了很多

    的坏点,因此实际复杂度并不是很高。

    和前一篇最直接的动态规划相比,如果背包容量和物品重量的量级相差不大而

    物品选择很多时,用直接动态规划方法效果可能更好。

    而如果出现入本文开头引入的情况,即背包容量量级很大,而可选物品很少时,

    用优化算法要快很多。因此,具体哪种好要视情况而定。

    因为博客园编辑公式不太方便,因此写好了文档再截屏的。 以上内容为原创,希望能帮到大家。

  • 相关阅读:
    (OK) [android-x86-6.0-rc1] grub
    /proc/sys/net/ipv4/conf/*/promote_secondaries
    (OK) Ipsysctl tutorial 1.0.4
    Android Netd ndc (Native Daemon Connector)
    Android Wi-Fi — IP forward — ndc — netd
    Android 网络问题
    有哪些 Android 大牛的 blog 值得推荐?
    Android 4.4 Kitkat 使能有线网络 Ethernet
    IP forwarding failure in android 4.0
    (OK) [android-x86-6.0-rc1] /system/etc/init.sh
  • 原文地址:https://www.cnblogs.com/xiaotan-code/p/6674902.html
Copyright © 2011-2022 走看看