欢迎光临 主页! [加入收藏] [设为首页]

0019算法笔记——【动态规划】0-1bt365官网网址

2018-09-09 02:14 小编: admin

 1、问题提出异议

     倘若n项和独一背包。。突出I的附加加重值于为Wi,它的付出代价是VI,背包的大量是C。问:我必然要多少选择要装入背包的签订协议?,因而,背包中装载的签订协议的总付出代价最大?

     拘泥于形式提出异议:倘若C >0, wi >0, vi >0 , 1无i或无n,we的尽量的格形式必要找到n矢径(x1)。,x2,…,xn,), xi∈{0,1}, ∋ ∑ wi xi≤c,且∑ vi XI遂愿最大值的。这是独一特别的圆整数项目问题。。

       2、最优性规律

     设(y1,y2,…,YN)是的 最优解。(Y2),…,YN)是的上面相符合子问题的独一最优解:

     证实:运用相反的办法。。若另外,设(z2,z3,…,Zn)是是你这么说的嘛!子问题的最优解。,而(y2,y3,…,Yn)过失它的最优解。。显然有
∑vizi > ∑viyi   (i=2,…,n)
且                           w1y1+ ∑wizi<= c
因而                       v1y1+ ∑vizi (i=2,…,n) > ∑ viyi, (i=1,…,n) 
阐明(y1,z2, z3,…,zn)是()0-1bt365官网网址的独一更优解,导出(y1,y2,…,yn)过失bt365官网网址的最优解,否认。

       3、递推相干

    设所给0-1bt365官网网址的子问题

     

     m(i)的最佳值,j),即,M(i),J)背包大量为J,可选择的突出是I。,i+1,…,n时0-1bt365官网网址的最优值。由0-1bt365官网网址的最优子建筑物技能,你可以创立M(i),J的复回

     睬:()背包大量为J。,可选择的突出是I。。在决议XI较晚地,,问题是两种社会地位经过。
    (1)背包余渣大量J,无赢得。;
(2)余渣大量J-WI,效益付出代价补充物;
算法的详细编码列举如下:

  1.   
  2. #include ""  
  3. #include    
  4. using namespace std;   
  5.   
  6. const int N = 4;  
  7.   
  8. void Knapsack(int v[],int w[],int c,int n,int m[][10]);  
  9. void Traceback(int m[][10],int w[],int c,int n,int x[]);  
  10.   
  11. int main()  
  12. {  
  13.     int c=8;  
  14.     int v[]={0,2,1,4,3},w[]={0,1,4,2,3};  
  15.     int x[N+1];  
  16.     int m[10][10];  
  17.   
  18.     cout<<要衬垫物的突出的附加加重值于别离为::"<
  19.     for(int i=1; i<=N; i++)  
  20.     {  
  21.         cout<" ";  
  22.     }  
  23.     cout<
  24.   
  25.     cout<<商品的付出代价别离是::"<
  26.     for(int i=1; i<=N; i++)  
  27.     {  
  28.         cout<" ";  
  29.     }  
  30.     cout<
  31.   
  32. 背包(V),w,c,N,m);  
  33.   
  34.     cout<<背包的最大值的可以是:"<
  35.   
  36. Traceback,w,c,N,x);  
  37.     cout<<包装后的签订协议被编号。:"<
  38.     for(int i=1; i<=N; i++)  
  39.     {  
  40.         if(x[i]==1)  
  41.         {  
  42.             cout<" ";  
  43.         }  
  44.     }  
  45.     cout<
  46.   
  47.     return 0;  
  48. }  
  49.   
  50. void Knapsack(int v[],int w[],int c,int n,int m[][10])  
  51. {  
  52.     intJMAX=min(W[N] - 1),c);  
  53.     for(int j=0; j<=jMax;j++)  
  54.     {  
  55.         m[n][j]=0;  
  56.     }  
  57.   
  58.     for(int j=w[n]; j<=c; j++)  
  59.     {  
  60.         m[n][j] = v[n];  
  61.     }  
  62.   
  63.     for(int i=n-1; i>1; i--)  
  64.     {  
  65. JMAX=min(W[i])- 1,c);  
  66.         for(int j=0; j<=jMax; j++)  
  67.         {  
  68. M[i] [j]=m〔i+1〕[j]  
  69.         }  
  70.   
  71.         for(int j=w[i]; j<=c; j++)   
  72.         {  
  73.             m[i][j] = max(m[i+1][j],M[i 1]〔J-W[i]〕 V[I]  
  74.         }  
  75.     }  
  76.     m[1][c] = m[2][c];  
  77.     if(c>=w[1])  
  78.     {  
  79. M〔1〕[C]=max(M〔1〕[C],M〔2〕〔C-W〔1〕〕 V〔1〕
  80.     }  
  81. }  
  82.   
  83.   
  84. void Traceback(int m[][10],int w[],int c,int n,int x[])  
  85. {  
  86.     for(int i=1; i
  87.     {  
  88.         if(m[i] [c]=m[i 1] [c]
  89.         {  
  90.             x[i]=0;  
  91.         }  
  92.         else  
  93.         {  
  94.             x[i]=1;  
  95.             c-=w[i];  
  96.         }  
  97.     }  
  98.     x[n]=(m[n][c])?1:0;  
  99. }  

     M[][]衬垫和Traceback回溯算法管理迅速移动:

      从m(i,J的复回悠闲地笔记。,算法背包必要O(NC)来计算工夫。 追踪必要O(n)来计算工夫。;该算法必要O(NC)计算工夫。。当背包大量C特别的大时,该算法必要更多的计算工夫。。比如,当c>2^n时,该算法必要Omega(N2^ n)计算工夫。。

         4、算法改良
     由m(i,J的复回版本悠闲地证实。,在一般情况下,在流行说得中肯每独一决定的I(无或无1),应变量m(i,j)是变量j的梯形编队单调的应变量。。猛长点是这一类应变量的提出异议特点。在一般情况下,应变量m(i,J)是由它所其说得中肯一部分猛长点但是决议的。。如图所示。

     在流行说得中肯每独一决定的I(无或无1),用表P[i]回忆应变量m(i),J的尽量的跳点。表P[i]可以计算m(i),从表P[i 1复回复回计算],初始工夫为p[n 1]={(0)。,0)}。 
独一要求:n=3,c=6,w={4,3,2},v={5,2,1}。

     应变量m(i,j)是独一应变量m(i+1),j)和应变量m(i+1),J-Wi) VI是经过评分斯运算流行的。。因而,应变量m(i,J的尽量的跳点计入于应变量m(i+1,J的跳点集p[i 1 ]和应变量m(i+1),J-Wi) VI的跳点集q[i 1]及其集中性。。易知,(s,t)q[i 1 ]当且仅当WI<=s<=c且(s-wi,t-六)∈p[i+1]。因而,容易由p[i+1]决定猛长点集q[i+1]列举如下:

q[i+1]=p[i+1]⊕(wi,六)={(j+wi,m(i,j)+六)|(j,m(i,j))∈p[i+1]}

    在另一方面,集中(A),b)和(c,d)是p[i+1 ]q[i 1 ]说得中肯2个跳点,当C>=A和D时q[i 1 ]说得中肯其它跳点是p[i]说得中肯尽量的蹦跳点。。

    由此可见,从表P[i 1 ]复回计算表P[i],q[i 1 ]可先由p[i 1 ]计算,那时的合表p[i 1 ]和表q[i 1],剪下把持跳点获得表P[i]。

      例:n=5,c=10,w={2,2,6,5,4},v={6,3,5,4,6}。猛长点的计算迅速移动列举如下。:

    初始工夫为p〔6〕={(0)。,0)},(w5,V5)=(4),6)。因而,q〔6〕=P〔6〕(W5),V5)={(4),6)}。 p[5]={(0,0),(4,6)}。q〔5〕=P〔5〕(W4),v4)={(5,4),(9,10)}。从跳点集P[5 ]和q[5 ]的兼有P〔5〕q[5]={(0,0),(4,6),(5,4),(9,10)参观}说得中肯蹦跳点(5),4)猛长点把持(4),6)。把持跳点(5),4)赚钱后,获得

     p[4]={(0,0),(4,6),(9,10)}
q〔4〕=P〔4〕〉(6),5)={(6,5),(10,11)}
p[3]={(0,0),(4,6),(9,10),(10,11)}
q〔3〕=P〔3〕〉(2),3)={(2,3),(6,9)}
p[2]={(0,0),(2,3),(4,6),(6,9),(9,10),(10,11)}
q〔2〕=P〔2〕〉(2),6)={(2,6),(4,9),(6,12),(8,15)}
p[1]={(0,0),(2,6),(4,9),(6,12),(8,15)}
P〔1〕(8)的终于一跳点,15)最优值为m(1)。,c)=15。

    详细编码实施列举如下:

  1.   
  2. #include ""  
  3. #include    
  4. using namespace std;   
  5.   
  6. const int N = 4;  
  7.   
  8. template<class Type>  
  9. int Knapsack(int n,Type c,V型,Type w[],int **p,int x[]);  
  10. template<class Type>  
  11. void Traceback(int n,Type w[],V型,典型**P,int *head,int x[]);  
  12.   
  13. int main()  
  14. {  
  15.     int c=8;  
  16.     int v[]={0,2,1,4,3},w[]={0,1,4,2,3};  
  17.     int x[N+1];  
  18.   
  19.     int **p = new int *[50];  
  20.     for(int i=0;i<50;i++)    
  21.     {    
  22.         p[i] = new int[2];  
  23.     }   
  24.   
  25.     cout<<要衬垫物的突出的附加加重值于别离为::"<
  26.     for(int i=1; i<=N; i++)  
  27.     {  
  28.         cout<" ";  
  29.     }  
  30.     cout<
  31.   
  32.     cout<<商品的付出代价别离是::"<
  33.     for(int i=1; i<=N; i++)  
  34.     {  
  35.         cout<" ";  
  36.     }  
  37.     cout<
  38.   
  39.     cout<<背包的最大值的可以是:"<
  40.   
  41.     cout<<包装后的签订协议被编号。:"<
  42.     for(int i=1; i<=N; i++)  
  43.     {  
  44.         if(x[i]==1)  
  45.         {  
  46.             cout<" ";  
  47.         }  
  48.     }  
  49.     cout<
  50.   
  51.     for(int i=0;i<50;i++)    
  52.     {    
  53.         delete p[i];  
  54.     }   
  55.   
  56.     delete[] p;  
  57.   
  58.     return 0;  
  59. }  
  60.   
  61. template<class Type>  
  62. int Knapsack(int n,Type c,V型,Type w[],int **p,int x[])  
  63. {  
  64.     int *head = new int[n+2];  
  65. 头[n 1]=0
  66.   
  67.     p[0][0]=0;  
  68.     p[0][1]=0;  
  69.   
  70.       
  71.       
  72.     int左= 0,右=0,下独一= 1  
  73.     head[n]=1;  
  74.   
  75.     for(int i=n; i>=1; i--)  
  76.     {  
  77.         intK =左  
  78.         for(int j=left; j<=right; j++)  
  79.         {  
  80.             if(p[j][0]+w[i]>c) break;  
  81.             Type y = p[j][0] + w[i],m = p[j][1] + v[i];  
  82.   
  83.               
  84.             while(k<=right && p[k][0]
  85.             {  
  86.     P[下一步]〔0〕=P[K]〔0〕
  87.                 p[next++][1]=p[k++][1];  
  88.             }  
  89.   
  90.               
  91.             if(k<=right && p[k][0]==y)  
  92.             {  
  93.                 if(m  
  94.                 {  
  95.                     m=p[k][1];  
  96.                 }  
  97.                 k++;  
  98.             }  
  99.   
  100.               
  101.               
  102.             if(m>p[next-1][1])  
  103.             {  
  104.                 p[next][0]=y;  
  105.                 p[next++][1]=m;  
  106.             }  
  107.   
  108.               
  109.             while(k<=right && p[k][1]<=p[next-1][1])  
  110.             {  
  111.                 k++;  
  112.             }  
  113.         }  
  114.   
  115.         while(k<=right)  
  116.         {  
  117. P[下一步]〔0〕=P[K]〔0〕
  118.             p[next++][1]=p[k++][1];  
  119.         }  
  120.   
  121. 左=右 1
  122. 右=下独一- 1
  123.   
  124.           
  125. 头[I-1 ] =下独一
  126.     }  
  127.   
  128. Traceback(n),w,v,p,head,x);  
  129.     return p[next-1][1];  
  130. }  
  131.   
  132.   
  133. template<class Type>  
  134. void Traceback(int n,Type w[],V型,典型**P,int *head,int x[])  
  135. {  
  136.       
  137.       
  138. 典型j=P〔头〔0〕- 1〕〔0〕,M=P〔头〔0〕- 1〕〔1〕
  139.     for(int i=1; i<=n; i++)  
  140.     {  
  141.         x[i]=0;  
  142.         for(int k=head[i+1]; k<=head[i]-1;k++)  
  143.         {  
  144.               
  145.             if(p[k][0]+w[i]==j && p[k][1]+v[i]==m)  
  146.             {  
  147.                 x[i]=1;  
  148.                 j=p[k][0];  
  149.                 m=p[k][1];  
  150.                 break;  
  151.             }  
  152.         }  
  153.     }  
  154. }  

     是你这么说的嘛!算法的次要计算是跳点S的计算。。鉴于q[i 1]=p[i 2](WI),六),因而,计算q[i 1 ]必要O(π[i 1)]计算工夫。。合p[i+1]和q[i+1]并赚钱受控猛长点也必要O(|p[i+1]|)计算工夫。从跳点集p[i]的限界可以看出,P[i]说得中肯猛长点对应于XI。,…,Xn的0/1诊断。因而,p[i]说得中肯跳点数不超过2 ^(n- i 1)。由此可见,该算法必要破费工夫来计算跳点集P[i]那么,改良算法的计算复杂性为O(2 ^ n)。。当倘若项Wi(1或无I)的附加加重值于为圆整数时。,|p[i]|≤c+1,(1≤i≤n)。在这种情况下,改良算法的计算复杂性为O(min {NC)。,2^n})。

运转树或花草结果显示在Fig.。:

个性化推荐

发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价: