0-1背包问题的算法与研究 优化作业

合集下载

0-1背包问题

0-1背包问题

0/1背包问题一、问题描述已知一个容量为M的背包和n件物品,物品编号为0~n-1,第i件物品的重量为w i,若将其装入背包将获益p i。

这里w i>0, p i >0(0≤i<n)。

所谓的0/1背包问题,是指在物品只能整件装入或不装入的情况下,求一种使得总效益最大的装载方案。

上述问题可形式化描述为:给定M>0,w i>0, p i>0(0≤i<n),求一个n元向量x=(x0,x1,…,x n-1),x i∈{0,1}(0≤i<n)使得∑<≤ni0w i x i≤M且∑<≤nip i x i最大。

为了叙述方便将该问题简记为KNAP(0,n-1,M)。

二、递归法求解1.分析已知x i∈{0,1},0≤i<n,假定对x i 作决策的次序是x=(x n-1,x n-2,…,x0),在对x n-1作出决策时存在以下两种情况:(1)x n-1=1,将编号为n-1的物品装入包中,接着求解子问题KNAP(0,n-2,M-w n-1);(2)x n-1=0,不将编号为n-1的物品装入包中,接着求解子问题KNAP(0,n-2,M)。

设f(j,X)是当背包容量为X ,可供选择的物品为0,1,…,j 时的最优解(即最大总效益),那么f(n-1,M)可表示为:f(n-1,M)=max{f(n-2,M),f(n-2,M-w n-1)+p n-1}对于任意的j ,0≤j <n,有f(j,X)=max{f(j-1,X),f(j-1,X-w j )+p j } 若将物品j 装入包中,则f(j,X)= f(j-1,X-w j )+p j反之f(j,X)= f(j-1,X)2.算法(1)f(-1,X)=⎩⎨⎧≥<∞-)0(0)0(X X ;(2)f(j,X)= max{f(j-1,X),f(j-1,X-w j )+p j } 其中0≤j <n 。

3.考虑以下背包问题,n=3, (w 0,w 1,w 2)=(2,3,4),(p 0,p 1,p 2)=(1,2,5)和M=6。

算法设计与分析实验报告—01背包问题

算法设计与分析实验报告—01背包问题

算法设计与分析实验报告—0/1背包问题-【问题描述】给定n 种物品和一个背包。

物品i 的重量是iw ,其价值为i v,背包容量为C 。

问应该如何选择装入背包的物品,使得装入背包中物品的总价值最大?【问题分析】0/1背包问题的可形式化描述为:给定C>0, i w >0, i v >0,1i n ≤≤,要求找出n 元0/1向量{}12(,,...,),0,1,1n i x x x x i n ∈≤≤,使得n1i i i w x c =≤∑,而且n1i ii v x=∑达到最大。

因此0/1背包问题是一个特殊的整数规划问题。

0n k w ≤≤1max ni i i v x =∑n1i ii w xc =≤∑{}0,1,1i x i n ∈≤≤【算法设计】设0/1背包问题的最优值为m( i, j ),即背包容量是j ,可选择物品为i,i+1,…,n 时0/1背包问题的最优值。

由0/1背包问题的最优子结构性质,可以建立计算m( i, j )的递归式如下:max{m( i+1, j ), m( i+1, j-i w )+i v } i j w ≥m( i, j )=m(i+1,j)n v n j w >m(n,j)=0 0n k w ≤≤【算法实现】#include <iostream.h> #include<string.h> #include<iomanip.h>int min(int w, int c) {int temp; if (w < c) temp = w;elsetemp = c;return temp;}Int max(int w, int c) {int temp; if (w > c) temp = w;elsetemp = c;return temp;}void knapsack(int v[], int w[], int** m, int c, int n) //求最优值 {int jmax = min(w[n]-1, c);for (int j = 0; j <= jmax; j++)m[n][j] = 0;for (int jj = w[n]; jj <= c; jj++)m[n][jj] = v[n];for(int i = n-1; i > 1; i--)//递归部分{jmax = min(w[i]-1, c);for(int j = 0; j <= jmax; j++)m[i][j] = m[i+1][j];for(int jj = w[i]; jj <= c; jj++)m[i][jj] = max(m[i+1][jj], m[i+1][jj-w[i]]+v[i]);}m[1][c] = m[2][c];if(c >= w[1])m[1][c] = max(m[1][c], m[2][c-w[1]]+v[1]);cout << endl << "最优值:" << m[1][c] << endl;cout<<endl;cout<< "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << endl;}int traceback(int x[], int w[], int** m, int c, int n) //回代,求最优解{out << endl << "得到的一组最优解如下: " << endl;for(int i = 1; i < n; i++){if(m[i][c] == m[i+1][c]) x[i] = 0;else{x[i] = 1;c -= w[i];}}x[n] = (m[n][c]) ? 1:0;for(int y = 1; y <= n; y++)cout << x[y] << "\t";cout << endl;return x[n];}void main(){int n, c;int **m;cout << "&&&&&&&&&&&&&&&&&&&&&欢迎使用0-1背包问题程序&&&&&&&&&&&&&&&&&&&" << endl;cout << "请输入物品个数: ";cin >> n ;cout << endl << "请输入背包的承重:";cin >> c;int *v = new int[n+1];cout << endl << "请输入每个物品的价值 (v[i]): " << endl;for(int i = 1; i <= n; i++)cin >> v[i];int *w = new int[n+1];cout << endl << "请输入每个物品的重量 (w[i]): " << endl;for(int j = 1; j <= n; j++)cin >> w[j];int *x = new int[n+1];m = new int* [n+1]; //动态的分配二维数组for(int p = 0; p < n+1; p++)m[p] = new int[c+1];knapsack (v, w, m, c, n);traceback(x, w, m, c, n);}【运行结果】。

01背包实验报告

01背包实验报告

算法设计与分析实验报告0_1背包一.问题描述假设有n件物品,每件物品有各自的重量W1,W2,……,Wn和与之对应的价值V1,V2,……,Vn。

设背包的容量为c,在不超过背包容量的前提下,求出获得最大价值总和的方案。

(0-1背包的情况下物品不可分割,只能选择放入,或者不放入背包中)。

二.求解思路1.贪心策略问题开始阶段,将所有物品按价值从高到低排列,每一次往背包里放入不超过背包容量的价值最大的物品,直到没有物品可放入为止。

但事实证明,由于物品的不可分割性,0-1背包并不适合贪心策略。

例:假设背包的容量为50,共有三件物品(重量,价值):(10,60),(20,100),(30,120)。

若使用贪心策略,则会选择一个(30,120)和一个(20,100)。

得到的价值总和是220。

而稍加计算便可知选取两个(20,100)和一个(10,60)可以得到更大的价值总和260。

因此贪心策略不能给出0-1背包的最优解。

后话:即使是普通背包问题(物品可分割),每次选择价值最大的物品也不能得到最优解。

正确的贪心策略应是:每次选择单位重量下价值最大的物品。

由于本次实验主要讨论的是0-1背包问题,这里就不给出该贪心策略的证明。

2.动态规划(1)证明0-1背包问题具有最优子结构性质:假设(x1,x2,……,xn)是容量为c的背包的一组最优解,其中xi的取值为0或1,表示是否放入背包中。

则必有(x2,x3,……,xn)为如下子问题的一组最优解:sum{xi*wi} (2<=i<=n)<=c-x1*w1利用反证法证明,假设(y1,y2,……,yn)是该子问题的一组最优解而(x2,x3,……,xn)不是。

则sum{yi*vi} > sum{xi*vi} (2<=i<=n)那么就可得到:x1*v1+ sum{yi*vi} > x1*v1+ sum{xi*vi} (2<=i<=n)则(x1,y2,……,yn)是原问题的最优解,而(x1,x2,……,xn)不是,与假设矛盾。

实验四0-1背包问题

实验四0-1背包问题

实验四“0-1”背包问题一、实验目的与要求熟悉C/C++语言的集成开发环境;通过本实验加深对贪心算法、动态规划算法的理解。

二、实验内容:掌握贪心算法、动态规划算法的概念和基本思想,分析并掌握“0-1”背包问题的求解方法,并分析其优缺点。

三、实验题1.“0-1”背包问题的贪心算法2.“0-1”背包问题的动态规划算法说明:背包实例采用教材P132习题六的6-1中的描述。

要求每种的算法都给出最大收益和最优解。

设有背包问题实例n=7,M=15,,(w0,w1,。

w6)=(2,3,5,7,1,4,1),物品装入背包的收益为:(p0,p1,。

,p6)=(10,5,15,7,6,18,3)。

求这一实例的最优解和最大收益。

四、实验步骤理解算法思想和问题要求;编程实现题目要求;上机输入和调试自己所编的程序;验证分析实验结果;整理出实验报告。

五、实验程序// 贪心法求解#include<iostream>#include"iomanip"using namespace std;//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的数组,运用冒泡排序void AvgBenefitsSort(float *arry_avgp,float *arry_p,float *arry_w ); //获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物品最优解的数组和还可以装载物品的重量float GetBestBenifit(float*arry_p,float*arry_w,float*arry_x,float u);int main(){float w[7]={2,3,5,7,1,4,1}; //物品重量数组float p[7]={10,5,15,7,6,18,3}; //物品收益数组float avgp[7]={0}; //单位毒品的收益数组float x[7]={0}; //最后装载物品的最优解数组const float M=15; //背包所能的载重float ben=0; //最后的收益AvgBenefitsSort(avgp,p,w);ben=GetBestBenifit(p,w,x,M);cout<<endl<<ben<<endl; //输出最后的收益system("pause");return 0;}//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的数组,运用冒泡排序void AvgBenefitsSort(float *arry_avgp,float *arry_p,float *arry_w ) {//求出物品的单位收益for(int i=0;i<7;i++){arry_avgp[i]=arry_p[i]/arry_w[i];}cout<<endl;//把求出的单位收益排序,冒泡排序法int exchange=7;int bound=0;float temp=0;while(exchange){bound=exchange;exchange=0;for(int i=0;i<bound;i++){if(arry_avgp[i]<arry_avgp[i+1]){//交换单位收益数组temp=arry_avgp[i];arry_avgp[i]=arry_avgp[i+1];arry_avgp[i+1]=temp;//交换收益数组temp=arry_p[i];arry_p[i]=arry_p[i+1];arry_p[i+1]=temp;//交换重量数组temp=arry_w[i];arry_w[i]=arry_w[i+1];arry_w[i+1]=temp;exchange=i;}}}}//获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物品最优解的数组和还可以装载物品的重量float GetBestBenifit(float*arry_p,float*arry_w,float*arry_x,float u) {int i=0; //循环变量ifloat benifit=0; //最后收益while(i<7){if(u-arry_w[i]>0){arry_x[i]=arry_w[i]; //把当前物品重量缴入最优解数组benifit+=arry_p[i]; //收益增加当前物品收益u-=arry_w[i]; //背包还能载重量减去当前物品重量cout<<arry_x[i]<<" "; //输出最优解}i++;}return benifit; //返回最后收益}//动态规划法求解,不懂-----#include<stdio.h>#include<math.h>#define n 6void DKNAP(int p[],int w[],int M,const int m); void main(){int p[n+1],w[n+1];int M,i,j;int m=1;for(i=1;i<=n;i++){m=m*2;printf("\nin put the weight and the p:");scanf("%d %d",&w[i],&p[i]);}printf("%d",m);printf("\n in put the max weight M:");scanf("%d",&M);DKNAP(p,w,M,m);}void DKNAP(int p[],int w[],int M,const int m) {int p2[m],w2[m],pp,ww,px;int F[n+1],pk,q,k,l,h,u,i,j,next,max,s[n+1];F[0]=1;p2[1]=w2[1]=0;l=h=1;F[1]=next=2;for(i=1;i<n;i++){k=l;max=0;u=l;for(q=l;q<=h;q++)if((w2[q]+w[i]<=M)&&max<=w2[q]+w[i]){u=q;max=w2[q]+w[i];}for(j=l;j<=u;j++){pp=p2[j]+p[i];ww=w2[j]+w[i];while(k<=h&&w2[k]<ww){p2[next]=p2[k];w2[next]=w2[k];next++;k++;}if(k<=h&&w2[k]==ww){if(pp<=p2[k])pp=p2[k];k++;}else if(pp>p2[next-1]){p2[next]=pp;w2[next]=ww;next++;}while(k<=h&&p2[k]<=p2[next-1])k++;}while(k<=h){p2[next]=p2[k];w2[next]=w2[k];next=next+1;k++;}l=h+1;h=next-1;F[i+1]=next;}for(i=1;i<next;i++)printf("%2d%2d ",p2[i],w2[i]);for(i=n;i>0;i--){next=F[i];next--;pp=pk=p2[next];ww=w2[next];while(ww+w[i]>M&&next>F[i-1]){next=next-1;pp=p2[next];ww=w2[next];}if(ww+w[i]<=M&&next>F[i-1])px=pp+p[i];if(px>pk&&ww+w[i]<=M){s[i]=1;M=M-w[i];printf("M=%d ",M);}else s[i]=0;}for(i=1;i<=n;i++)printf("%2d ",s[i]);}六、实验结果1、贪心法截图:七、实验分析。

0-1背包问题的算法与研究优化作业

0-1背包问题的算法与研究优化作业

0-1背包问题的算法与研究优化作业0-1背包问题算法分析背包问题又称子集合问题,最早是由Dantzing 于20世纪50年代首次提出的,已成为计算机学科中一个经典的NP 问题 . 0-1背包问题在很多领域都有广泛的应用,很多实际问题都可转换为0-1背包问题,例如下料问题,贷款组合优化决策问题等,0-l 整数线性规划问题可以归结为0-1背包问题,而整数线性规划问题都可以转化为0-l 整数线性规划问题。

所以,对0-1背包问题求解方法的研究无论是在理论上还是在实践中都具有一定的意义。

一 0-1 背包问题的数学模型及其分类0-1 背包问题的数学模型如下:假设n 个物件,其重量用w i 表示,价值为p i (i =1,2,…, n ),背包的最大容纳重量为c,当物件i 被选入背包时,定义变量 x i =1,否则 x i =0。

现在考虑 n 个物件的选择与否,则背包内 n 个物件总重量为Σw i x i ,物件的总价值为Σp i x i ,如何决定变量x i (i =1,2,…,n )的值(即确定一个物件组合)使背包内物件总价值为最大,其数学模型表示如下:{ 0..max 11≤∑∑==i n i i i n i i x w t s x p到目前为止,求解0-1背包问题的方法很多,精确算法有分支限界法,动态规划法等,近似算法有贪婪方法、蚁群算法等。

一般来说,精确算法不能在较短时间内求解大规模0-1背包问题,使其实用性受到限制。

而近似算法只能求解问题的近似解,有时所得的近似解质量很低。

本文主要针对常见的求解0-1背包问题的算法设计方法进行阐述.二算法思想描述及其性能分析1 分支界限法第一个基于分支界限法的背包问题求解是由Horowit znd Sahni,Nauss and Martello and T oth 于20世纪70年代提出.分支界限法的基本思想是对有约束条件的最优化问题的所有可行解(数目有限)空间进行搜索.该算法在具体执行时,把全部可行的解空间不断分割为越来越小的子集(成为分支),并为每个子集内的解的值计算一个下界或上界(称为定界).在每次分支后,对凡是界限超出已知可行解值的那些子集不再做进一步分支.这样,解的许多子集(即搜索树上的许多结点)就可以不予考虑了,从而缩小了搜索范围.这一过程一直进行到找出可行解为止,该可行解的值不大于任何子集的界限,因此这种算法一般可以求得最优解.分支界限法是组合优化问题的有效求解方法,对于0-1背包问题,其计算步骤如下所述:(1) 计算每个节点即解集中部分物品的重量和。

0-1背包问

0-1背包问

实验四:动态规划 0-1背包问题一、 实验目的与要求1、明确0-1背包问题的概念2、利用动态规划解决0-1背包问题问题二、实验题:0-1背包问题(knapsack problem),某商店有n 个物品,第i 个物品价值为vi ,重量(或称权值)为wi ,其中vi 和wi 为非负数, 背包的容量为W ,W 为一非负数。

目标是如何选择装入背包的物品,使装入背包的物品总价值最大,所选商品的一个可行解即所选商品的序列如何?背包问题与0-1背包问题的不同点在于,在选择物品装入背包时,可以只选择物品的一部分,而不一定要选择物品的全部。

可将这个问题形式描述如下:约束条件为:举例:若商店一共有5类商品,重量分别为:3,4,7,8,9价值分别为:4,5,10,11,13则:所选商品的最大价值为24所选商品的一个序列为:0 0 0 1 1#include <iostream>using namespace std;#define N 6 //物品的个数为N-1,5#define C 11 //背包的容量为C-1,10int max(int number1,int number2); //声明所需函数maxint KnapSack(int w[],int v[]); //声明0/1背包问题算法void main(){int v[N]={0,6,3,5,4,6};int w[N]={0,2,2,6,5,4};cout<<"背包容量为:"<<C-1<<endl;cout<<"物品的价值分别是:";for(int j=1;j<=5;j++)∑≤≤n i i i x v 1max }1,0{,1∈≤∑≤≤i n i i i x W x w{cout<<" "<<v[j]<<" ";}cout<<endl;cout<<"物品的重量分别是:";for(int i=1;i<=5;i++){cout<<" "<<w[i]<<" ";}cout<<endl;cout<<"最大价值为:";cout<<KnapSack(w,v)<<endl;}int max(int number1,int number2) //所需函数max{if(number1>number2) return number1;else return number2;}int KnapSack(int w[],int v[]) //0/1背包问题算法{int V[N][C];int x[N];int i;int j;for (i=0;i<=N-1;i++) //初始化第0列{ V[i][0]=0; }for (j=0;j<=C-1;j++) //初始化第0行{ V[0][j]=0; }for(i=1;i<=N-1;i++) //计算第i行,进行第i次迭代{for(j=1;j<=C-1;j++){if(j<w[i])V[i][j]=V[i-1][j];elseV[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]);}}int k=C-1; //求装入背包的物品for(i=N-1;i>0;i--){if(V[i][k]>V[i-1][k]){x[i]=1;k=k-w[i];}else x[i]=0;}return V[N-1][C-1]; //返回背包取得的最大值}。

背包问题实验报告

背包问题实验报告

0-1背包问题实验报告一:0-1背包问题给定n种物品和一个背包。

物品i的重量是Wi,其价值为Vi,背包的容量为c。

问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大?在选择装入背包的物品时,对每种物品i只有两种选择,装入或者不装入背包。

不能将物品i多次装入,也不能装入部分的物品i。

因此,该问题被称为0-1背包问题。

本次针对0-1背包问题的实验,主要使用动态规划的方法、贪心算法、回溯法以及分支限界法。

测试用例为:n=50,c=1000,每个物品重量为{220,208,198,192,180,180,165,162,160,158,155,130,125,122,120,118,115,110,105,1 01,100,100,98,96,95,90,88,82,80,77,75,73,70,69,66,65,63,60,58,56,50,30,20,15,10,8,5 ,3,1,1}每个物品价值为{80,82,85,70,72,70,66,50,55,25,50,55,40,48,50,32,22,60,30,32,40,38,35,32,25,28 ,30,22,50,30,45,30,60,50,20,65,20,25,30,10,20,25,15,10,10,10,4,4,2,1} 下面将分别谈论。

二:动态规划法1:基本思想:动态规划算法的基本思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

其经过分解得到的子问题往往不是相互独立的,可以用一张表来记录所有已解决的子问题的答案,而不论该子问题以后是否会用到。

从而使得子问题避免重复计算。

2:设计步骤:动态规划算法适用于解最优化问题,通常可按以下几步设计:(1)找出最优解的特性,并刻画其结构特征。

(2)递归地定义最优值。

(3)以自底向上的方式计算出最优值。

(4)根据计算最优值时得到的信息,构造最优解。

蚁群算法的0-1背包问题求解研究

蚁群算法的0-1背包问题求解研究

蚁群算法的0-1背包问题求解研究提出解决背包问题的蚁群算法思想及求解0-1背包问题问题描述,给出了改进常规的蚁群算法的方法。

标签:背包问题,蚁群算法,问题设计,算法改进1 问题描述0/1背包问题是指有不同价值、不同重量的物品n件,求从这n件物品中选取一部分物品且对每一物品,要么选,要么不选,满足被选物品的总重量不超过背包指定的限制重量且达到被选物品的价值总和最大的问题。

如果所有物品的重量之和小于背包的容量,则问题极其简单,所得利益也就是所有物品的价值之和。

2 蚁群算法的思想蚁群算法是模仿真实的蚁群行为而提出的一种模拟进化算法.蚂蚁之间是通过一种称为信息素(Pheromone)的物质传递信息的,蚂蚁在运动过程中能够在经过的路径上留下该种物质,而且能够感知这种物质的存在及其强度,并以此指导自己的运动方向.因此,由大量蚂蚁组成的集体行为便表现出一种信息正反馈现象:某一条路径上走过的蚂蚁越多,该路径上留下的信息素就越多,则后来者选择该路径的概率就越大.蚂蚁个体之间就是通过这种信息素的交流,搜索到一条从蚁巢到食物源的最短路径.3 利用蚁群算法求解0-1背包问题设计设有n个城市,d,(i,J=l,2,…,n)表示城市i和J间的距离,t.ij (t)表示在t时刻城市i和j之间的信息量,以此来模拟实际蚂蚁的分泌物。

设共有m只蚂蚁,用P.ij k表示在t时刻蚂蚁k由城市i转移到城市J的概率,则Pk.ij k(t)由城市i转移到城市J的概率,则τα.ij(t)ηβ.ij (t)∑r∈allowedkτα.ir(t)ηβ.ir(t)j∈allowdk0 otherwise其中,allowedk表示蚂蚁k下一步允许走过的城市的集合,表示路径上的信息量对蚂蚁选择路径所起的作用大小,η,为由城市i转移到城市j的期望程度,例如,可以取η.ij=1/d.ij。

β表示η.ij的作用。

当a=0时,算法就是传统的贪心算法;而当p=O时,就成了纯粹的正反馈的启发式算法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

0-1背包问题算法分析背包问题又称子集合问题,最早是由Dantzing 于20世纪50年代首次提出的,已成为计算机学科中一个经典的NP 问题 . 0-1背包问题在很多领域都有广泛的应用,很多实际问题都可转换为0-1背包问题,例如下料问题,贷款组合优化决策问题等,0-l 整数线性规划问题可以归结为0-1背包问题,而整数线性规划问题都可以转化为0-l 整数线性规划问题。

所以,对0-1背包问题求解方法的研究无论是在理论上还是在实践中都具有一定的意义。

一 0-1 背包问题的数学模型及其分类0-1 背包问题的数学模型如下:假设n 个物件,其重量用w i 表示,价值为p i (i =1,2,…, n ),背包的最大容纳重量为c,当物件i 被选入背包时,定义变量 x i =1,否则 x i =0。

现在考虑 n 个物件的选择与否,则背包内 n 个物件总重量为Σw i x i ,物件的总价值为Σp i x i ,如何决定变量x i (i =1,2,…,n )的值(即确定一个物件组合)使背包内物件总价值为最大,其数学模型表示如下:{ 0..max 11≤∑∑==i n i i i n i i x w t s x p到目前为止,求解0-1背包问题的方法很多,精确算法有分支限界法,动态规划法等,近似算法有贪婪方法、蚁群算法等。

一般来说,精确算法不能在较短时间内求解大规模0-1背包问题,使其实用性受到限制。

而近似算法只能求解问题的近似解,有时所得的近似解质量很低。

本文主要针对常见的求解0-1背包问题的算法设计方法进行阐述.二 算法思想描述及其性能分析1 分支界限法第一个基于分支界限法的背包问题求解是由Horowit znd Sahni,Nauss and Martello and Toth 于20世纪70年代提出.分支界限法的基本思想是对有约束条件的最优化问题的所有可行解(数目有限)空间进行搜索.该算法在具体执行时,把全部可行的解空间不断分割为越来越小的子集(成为分支),并为每个子集内的解的值计算一个下界或上界(称为定界).在每次分支后,对凡是界限超出已知可行解值的那些子集不再做进一步分支.这样,解的许多子集(即搜索树上的许多结点)就可以不予考虑了,从而缩小了搜索范围.这一过程一直进行到找出可行解为止,该可行解的值不大于任何子集的界限,因此这种算法一般可以求得最优解.分支界限法是组合优化问题的有效求解方法,对于0-1背包问题,其计算步骤如下所述:(1) 计算每个节点即解集中部分物品的重量和。

如当前重量超过背包容量w ,则将在该节点下的所有子树删除;(2) 计算上一级分支的所有可能解的价值,如果当前分支的价值比较小或相等则删除。

分支界限法并不用于纯粹的深度优先模式,而是最好优先:选择最优希望达到目标结点的结点优先扩展。

此算法由于从最小下界分支,每次算完限界后,把搜索树上当前所有的叶子结点的界限进行比较,找出限界最小的结点,此结点即为下次分支的结点。

这种决策的优点是检查子问题较少,能较快地求得最佳解。

在最坏情况下,不可避免地要在整个状态空间树上进行搜索,要存储很多叶子结点的限界和对应的耗费矩阵,需要数级的时间复杂度O (n2),此时其空间消耗也较大。

可以说一个分支定界求解方法的效率基本上由值界方法决定,若界估计不好,在极端情况下将于穷举搜索没多大区别。

2 动态规划法动态规划法DM (Dynamic Programming ,简称DM )是美国 数学家Bellman R E 等人20世纪50年代初在研究阶段决策过程的优化问题时提出的,把多阶段决策过程转化为一系列单阶段决策问题逐个求解,创立了解决这类过程优化问题的新方法—动态规划。

动态规划算法是先把问题分成多个子问题(一般地每个子问题是互相关联和影响的),再依次研究逐个问题的决策。

决策就是某个阶段的状态确定后,从该状态演变到下一阶段状态的选择。

当全体子问题都解决时,整体问题也随之解决。

用枚举的方法从所有可能的决策序列中去选取最优决策序列可能是较费时的笨拙方法,但利用最优性原理去找出递推关系,再找最优决策序列就可能使得枚举数量大大下降,这就是动态规划方法设计算法的主要思路。

设F k (y )为背包只装前k 种东西,总重限制为y 的情况下所具有的最大价值,即 )0()0(max )(11b y y xw n k x p y F i k i i i ki i k ≤≤≤≤≤=∑∑==这两个式子分别为背包问题子问题的目标函数和约束条件,不难看出是满足优化原则的。

使用动态规划法求解,所得递推公式和边界条件是:F k (y )=max (F k -1(y ),F (y -w k )+p k ),F 0(y )=0,对一切 y ,0≤y ≤c , F k (y )=0,对一切 y ,0≤k ≤n , F 1(y )=[y/w 1]·p 1用动态规划方法求解 0-1 背包问题的过程如下:①将问题分解为若干个子问题(一般每个子问题是相互关联和影响的 ),再依次研究逐个问题的决策,也就是把整个问题的最优解与子 问题的局部最优解用递推等式联系起来;②定义边界条件;③把边界条件代入递推公式,逐步求得最优解。

动态规划算法是一种经典的背包问题求解算法,其原理简单,算法思路清晰易于实现。

动态规划算法虽然高效,但是对于规模较大的问题它并不是一个理想的算法,最重要的原因就是它的维数障碍,即计算和存储量的需要对于状态空间和决策空间的维数的增长呈指数增长关系。

这样惊人的增长速度是计算机难以承受的,这就使得直接的动态规划方法求解规划较大的背包问题发生了困难,且目前尚没有好的解决办法。

3 蚁群算法蚁群算法由意大利学者 Dorigo 等人首先提出,是模仿真实的蚁群行为而提出的一种模拟进化算法。

蚂蚁之间是通过一种称为信息 素(Pheromone )的物质传递信息的,蚂蚁能够在经过的路径上留下该种物质,而且能够感知这种物质的存在及其强度,并以此来指导自己的运动方向。

因此,由大量蚂蚁组成的集体行为便表现出一种信息正反馈现象:某一条路径上走过的蚂蚁越多,该路径上留下的信息素就越多,则后来者选择该路径的概率就越大。

蚂蚁之间就是通过这种信息素的交流,搜索到一条从蚁巢到食物源的最短路径。

将这一问题的核心运用到背包问题中:在某一物品上聚集的信息素越多,则该物品被选择的概率就越大。

就蚁群算法而言,当处理的数据比较小时,其具有很快的收敛速度 ,而随着数据规模的增大,算法的收敛速度明显降低。

假设有m 只蚂蚁,n +1个城市,第o 个城市代表背包,第1~n 个城市代表各个物品。

把第o 个城市看成蚂蚁的寻优起点。

令 n ij =p i / w i 表示蚂蚁从城市转移到城市的期望程度,这样价值越高同时重量越小的物品对蚂蚁的吸引就越大 。

令 e ij 表示路径中留下的信息素强度。

任一只蚂蚁 k 由城市 i 转移到城市j 的概率可设为:),2,1,0(1n j i n e n e p n j b ija ijb ij a ij k ij ===∑= 其中α表示路径上的信息量对蚂蚁选择路径所起的作用大小,β 为吸引度的重要性。

每只蚂蚁从寻优起点出发只需一步就可到达 1~n 当中任意一个食物源,所以上式中有 (i =1,2,…,n )。

寻优过程由多只蚂蚁进行,当每只蚂蚁以较大的概率选中食物源 j 时,如果有c -Σw i x i ≥0,则变量xj 将加1,否则给从i 到 j 的路径以罚值,以使后续的蚂蚁不再选择本路径。

当所有节点都受罚以后将结束一次求解过程。

然后记录最优解,更新信息素。

更新的公式可为Δe ij =Q*w j *x je ij (t +1)=(1-ρ)*e ij (t )+Δe ij (i =0,j =1,2,…,n )上式 中 ρ 为挥发系数,Q 为正常数,x j 为经过该路径的蚂蚁数量。

用蚁群算法求解 0-1 背包问题的过程如下:①初始化:即将任意两个城市之间的道路上的信息素赋一个初值;②搜索:让若干只蚂蚁根据信息素和距离选择城市;③每到一个新城市,进行信息素局部更新;④所有蚂蚁完成回路后,进行全局信息素更新;⑤记录最优路径,返回步骤②循环直到满足退出条件。

蚁群算法是近年来发展起来的一种随机算法,已经证明可以有效解决背包问题。

但是蚁群算法的收敛性证明尚处于初步阶段,缺乏完善的理论基础。

并且在减少寻优计算量和缩短算法运行时间方面,有待进一步改进。

4 贪婪法贪婪算法通过一系列的选择得到问题的解,在每一次总是做出在当前状态下看来是最好的选择,也就是希望通过局部的最优来达到一个全局的最优。

这种启发式的策略并不总能获得最优解,然而在许多情况下确能达到预期的目的,而且对于很多N-P问题来说,本身就不存在最优解。

对于0-1背包问题来说,贪婪的策略有常用的3种。

每种贪婪策略都采用多步过程来完成背包的装入。

在每一步过程中利用贪婪准则选择一个物品装入背包。

第一种贪婪准则:从剩余的物品中,选出可以装入背包的价值最大的物品,利用这种规则,价值最大的物品首先被装入(假设有足够容量),然后是下一个价值最大的物品,如此继续下去。

第二种贪婪准则:从剩下的物品中选择可装入背包的重量最小的物品,如此继续下去直到不能满足条件为止。

第三种贪婪准则:价值密度(价值重量比p i/w i)贪婪算法,这种选择准则为:从剩余物品中选择可装入包的p i/w i值最大的物品,这也是本文所选择的贪婪策略,因为它是一个直觉上近似的解。

用贪婪算法求解0-1背包问题的过程如下:①对于给定的物品,分别求出价值密度(价值重量比),r i=p i/w i,i=1,2,…,n;②忽略先前的物品排序,按照价值密度,进行非升序排列:(p(1)/w(1)≥(p(2)/w (2)≥…≥(p(n)/w (n));③重复以下步骤,直到不满足条件为止:对于当前的物品,如果重量小于包中剩余的容量,则放入并置物品标志为1(表明被选中),否则就停止。

算法主要耗时是在于将各种物品按价值密度大小排序,本文利用MATLAB软件中的SORTROWS函数进行排序,此函数是基于快速排序(quicksort)实现的,因此算法的时间复杂度为O(nlogn)。

其他算法和各种算法的改进除了以上介绍的算法外,还有DNA算法,人工神经网络,递归,回溯法,克隆选择算法,禁忌搜索与GA算法,混合算法等,由于各种算法都有自身的优点和不足,许多学者通过利用一种算法的有点同时通过结合其他算法避免该算法的不足,出现了混合算法,这些算法都取得了很大成功。

通过计算复杂度的研究表明0-1背包问题是一个经典的NP问题。

对于规模过大的0-1背包问题,人们还是无法找到完美的求解方法,所有智能算法都是在一定范围内求解。

相关文档
最新文档