遗传算法求解背包问题
基于改进遗传算法的背包问题求解技术研究
基于改进遗传算法的背包问题求解技术研究背包问题是一个经典的问题,它的应用在物流、采购、制造等领域广泛存在。
它的基本目标是在给定的载重量下,让所选物品的价值最大化。
但随着问题规模的增大,背包问题也变得越来越复杂,传统算法往往难以高效地解决问题。
因此,研究基于改进遗传算法的背包问题求解技术成为一种切实可行的方法。
一、背包问题的定义具体地来说,背包问题可以分为0/1背包问题和多重背包问题两种。
其中,0/1背包问题指在给定的背包容量下,从给出的n个物品中,选择一些物品放入一个背包中,每个物品要么全部被放下,要么不放。
而多重背包问题则允许在给定的n种物品中,从中选择任意数量的物品放入背包中,并且每个物品的重量和价值不同。
在0/1背包问题中,设物品数量为n,背包的容量为C,每件物品的重量为Wi,价值为Vi,求解背包能容纳的最大价值ΣVi,满足∑Wi≤C。
在多重背包问题中,同样设物品数量为n,背包的容量为C,每件物品的重量为Wi,价值为Vi,第i件物品的数量为Mi,求解背包能容纳的最大价值ΣVi,满足∑MiWi≤C。
二、传统算法的局限性对于小规模的背包问题,传统算法如贪心算法、动态规划等可以得到较好的解决。
但对于复杂的问题,传统算法的局限性也随之显现。
例如,在0/1背包问题中,当物品数量很大时,动态规划算法会出现状态数爆炸的问题,导致内存不足,程序崩溃。
针对这个问题,可以通过压缩状态空间、优化内存的方式来解决,但这些优化不可避免地会牺牲算法的准确性和效率。
在多重背包问题中,传统算法同样无法处理大规模问题。
传统的贪心算法可以得到近似最优解,但它无法保证求得的结果是全局最优的。
另外,当物品数量和价值的分布随机时,传统算法的效果越发不尽如人意。
更进一步地,传统算法无法解决背包问题的带约束函数问题。
带约束函数的背包问题可以表示为在可供选择的物品中,最大化价值函数,同时满足约束函数。
这样的问题在实际应用中普遍存在,如在某些国家的医院物流系统中,医生需要从供应商处选择药品、设备等物品来维持日常使用,但同时需要满足不同品种和不同状态的医用物品在仓库内的库存量比例不超过一定值。
遗传算法解决01背包问题
遗传算法解决01背包问题2015 ~2016 学年第二学期学生姓名专业学号2016年 6 月目录一:问题描述 (3)二:遗传算法原理及特点 (3)三:背包问题的遗传算法求解 (3)1.文字描述 (3)2.遗传算法中的抽象概念在背包问题的具体化 (3)3.算法求解的基本步骤 (4)四:算法实现 (4)1.数据结构 (4)2.部分代码 (5)五:结论 (8)六:参考文献 (8)一、问题描述0-1背包问题属于组合优化问题的一个例子,求解0-1背包问题的过程可以被视作在很多可行解当中求解一个最优解。
01背包问题的一般描述如下:给定n个物品和一个背包,物品i的重量为Wi,其价值为Vi,背包的容量为C。
问应如何选择合适的物品装入背包,使得背包中装入的物品的总价值最大。
注意的一点是,背包内的物品的重量之和不能大于背包的容量C。
在选择装入背包的物品时,对每种物品i只有两种选择:即装入背包或者不装入背包,不能讲物品i装入背包多次,也不能只装入部分的物品,称此类问题为0/1背包问题。
二、遗传算法原理及特点遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。
遗传算法有着鲜明的优点:(1)遗传算法的操作对象是一组可行解,而非单个可行解;搜索轨道有多条,而非单条,因而具有良好的并行性.(2)遗传算法只需利用目标的取值信息,而无需递度等高价值信息,因而适用于任何规模,高度非线形的不连续多峰函数的优化以及无解析表达式的目标函数的优化,具有很强的通用性.(3)遗传算法择优机制是一种“软”选择,加上良好的并行性,使它具有良好的全局优化性和稳健性.(4)遗传算法操作的可行解集是经过编码化的(通常采用二进制编码),目标函数解释为编码化个体(可行解)的适应值,因而具有良好的可操作性与简单性.三、背包问题的遗传算法求解1、文字描述0-1背包问题传统的解决方法有动态规划法、分支界限法、回溯法等等。
遗传算法求解0-1背包问题(JAVA)
遗传算法求解0-1背包问题一、问题描述给定n种物品和容量为C的背包。
物品i的重量是wi,其价值为vi。
问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?二、知识表示1、状态表示(1)个体或染色体:问题的一个解,表示为n个比特的字符串,比特值为0表示不选该物品,比特值为1表示选择该物品。
(2)基因:染色体的每一个比特。
(3)种群:解的集合。
(4)适应度:衡量个体优劣的函数值。
2、控制参数(1)种群规模:解的个数。
(2)最大遗传的代数(3)交叉率:参加交叉运算的染色体个数占全体染色体的比例,取值范围一般为0.4~0.99。
(4)变异率:发生变异的基因位数所占全体染色体的基因总位数的比例,取值范围一般为0.0001~0.1。
3、算法描述(1)在搜索空间U上定义一个适应度函数f(x),给定种群规模N,交叉率Pc和变异率Pm,代数T;(2)随机产生U中的N个个体s1, s2, …, sN,组成初始种群S={s1, s2, …, sN},置代数计数器t=1;(3)计算S中每个个体的适应度f() ;(4)若终止条件满足,则取S中适应度最大的个体作为所求结果,算法结束。
(5)按选择概率P(xi)所决定的选中机会,每次从S中随机选定1个个体并将其染色体复制,共做N次,然后将复制所得的N个染色体组成群体S1;(6)按交叉率Pc所决定的参加交叉的染色体数c,从S1中随机确定c个染色体,配对进行交叉操作,并用产生的新染色体代替原染色体,得群体S2;(7)按变异率P m所决定的变异次数m,从S2中随机确定m个染色体,分别进行变异操作,并用产生的新染色体代替原染色体,得群体S3;(8)将群体S3作为新一代种群,即用S3代替S,t = t+1,转步3。
三、算法实现1、主要的数据结构染色体:用一维数组表示,数组中下标为i的元素表示第(i+1)个物品的选中状态,元素值为1,表示物品被选中,元素值为0表示物品不被选中。
种群:用二维数组表示,每一行表示一个染色体。
遗传算法求解背包问题
遗传算法的过程:初始化:将计划装入背包的每个物品看成一个二进制串的一位,为1表示放入该物品,为0表示不放入该物品。
初始种群的产生:初始化前对放入背包物品数的一个预测(背包容积/物品最大体积),接下来只要在种群每条染色体中保证有(背包容积/物品最大体积)个为1的位初始化就完成了。
选择:选择进行杂交的父代染色体,被选中的父代染色体总是若干个染色体中最优(适应度最高)的,来保证向优化的方向发展。
详细的选择方法:随机产生2个数:Chrom_Cross_From, Chrom_Cross_To,当然得采用一定的手段来保证前者比后者小。
从Chrom_Cross_From到Chrom_Cross_To这Chrom_Cross_To-Chrom_Cross_From+1条染色体中选择最优(适应度最大)的染色体作为父代之一。
需要进行两次选择得到杂交的两条父代染色体。
这样做可以保证算法不会过早收敛。
函数实现:Individual Select(int ChromSize,Individual Pop[]){int Num_Selected,i,j,Chrom_Selected_From,Chrom_Selected_To,temp;Individual *Chrom_Selected;do{Chrom_Selected_From=rand()%PopSize;Chrom_Selected_To=rand()%PopSize;if(Chrom_Selected_From>Chrom_Selected_To){temp=Chrom_Selected_From;Chrom_Selected_From=Chrom_Selected_To;Chrom_Selected_To=temp;}Num_Selected=Chrom_Selected_To-Chrom_Selected_From+1;}while(Num_Selected<=0);Chrom_Selected=new Individual[Num_Selected];for(i=0;i<Num_Selected;i++)Chrom_Selected[i].chrom=new int[ChromSize];for(i=0,j=Chrom_Selected_From;i<Num_Selected,j<Chrom_Selected_To+1;i++,j++){Chrom_Selected[i]=Pop[j];}Order_Best_First(ChromSize,Num_Selected,Chrom_Selected);Chrom_Selected[0].fitness=Fitness(Chrom_Selected[0].chrom,ChromSize);return Chrom_Selected[0];}杂交:将两次选择得到的父代染色体进行杂交得到一条新的染色体,作为较新种群(并非新的种群)的一条染色体,杂交直到较新种群的染色体数等于原种群的染色体数。
用遗传算法求解多维背包问题
智能所“暑期学校”科研实习报告题目:用遗传算法求解多维背包问题姓名:吴逊专业:智能科学与技术指导老师姓名、职务:尚荣华副教授日期:二零一一年八月摘要首先简单介绍了基本的遗传算法。
然后将贪婪算法与简单遗传法相结合构成一种混合遗传算法,用该混合遗传算法求解背包问题。
通过对标准测试集中的27个问题进行测试,发现用这种方法求解大规模背包问题, 其解的质量和求解性能较简单遗传算法和贪婪算法都有所改善。
关键词:遗传算法,多维背包问题绪论遗传算法是模拟生物界自然进化过程的一种计算模型,其思想主要来源于达尔文进化论、孟德尔遗传学说及现代生物学对生命遗传过程的研究。
对它的研究起源于20世纪70年代,由美国Michigan大学的J.Holland教授于1975年正式提出。
GA的主要特点是群体搜索策略和群体中个体之间的信息交换,搜索不依赖于梯度信息。
尤其适用于处理传统搜索方法难于解决的复杂和非线性问题,可广泛用于组合优化、机器学习、自适应控制等领域。
本文将先就遗传算法介绍其思想来源及基本思路,并提出GA应用的5个关键点。
接着对一类典型的组合优化问题——0-1背包问题分别进行简单遗传算法与混合遗传算法的求解,并将结果与贪婪算法进行对比。
第一章遗传算法概述2.1达尔文进化论与孟德尔学说19世纪中叶,达尔文创立了科学的生物进化学说,它第一次对整个生物界的发生、发展,作出了唯物的、规律性的解释,使生物学发生了一次革命性的变革。
达尔文进化论认为生物不是静止的,而是进化的。
物种不断变异,旧物种消失,新物种产生。
而且生物的进化是连续和逐渐,不会发生突变。
生物之间存在一定的亲缘关系,他们具有共同的祖先;而另一方面,由于生物过渡繁殖,但是它们的生存空间和食物有限,从而面临生存斗争,包括:种内、种间以及生物与环境的斗争。
总结起来为两部分内容:遗传变异与自然选择。
其中自然选择是达尔文进化论的核心。
1857年,孟德尔通过对植物进行一系列仔细的实验。
遗传算法求解0 1背包问题(JAVA)
遗传算法求解0-1背包问题一、问题描述给定n种物品和容量为C的背包。
物品i的重量是wi,其价值为vi。
问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?二、知识表示1、状态表示(1)个体或染色体:问题的一个解,表示为n个比特的字符串,比特值为0表示不选该物品,比特值为1表示选择该物品。
(2)基因:染色体的每一个比特。
(3)种群:解的集合。
(4)适应度:衡量个体优劣的函数值。
2、控制参数(1)种群规模:解的个数。
(2)最大遗传的代数(3)交叉率:参加交叉运算的染色体个数占全体染色体的比例,取值范围一般为0.4~0.99。
(4)变异率:发生变异的基因位数所占全体染色体的基因总位数的比例,取值范围一般为0.0001~0.1。
3、算法描述(1)在搜索空间U上定义一个适应度函数f(x),给定种群规模N,交叉率Pc和变异率Pm,代数T;(2)随机产生U中的N个个体s1,s2,…,sN,组成初始种群S={s1,s2,…,sN},置代数计数器t=1;(3)计算S中每个个体的适应度f();(4)若终止条件满足,则取S中适应度最大的个体作为所求结果,算法结束。
(5)按选择概率P(xi)所决定的选中机会,每次从S中随机选定1个个体并将其染色体复制,共做N次,然后将复制所得的N个染色体组成群体S1;(6)按交叉率Pc所决定的参加交叉的染色体数c,从S1中随机确定c个染色体,配对进行交叉操作,并用产生的新染色体代替原染色体,得群体S2;(7)按变异率P m所决定的变异次数m,从S2中随机确定m个染色体,分别进行变异操作,并用产生的新染色体代替原染色体,得群体S3;(8)将群体S3作为新一代种群,即用S3代替S,t=t+1,转步3。
三、算法实现1、主要的数据结构染色体:用一维数组表示,数组中下标为i的元素表示第(i+1)个物品的选中状态,元素值为1,表示物品被选中,元素值为0表示物品不被选中。
种群:用二维数组表示,每一行表示一个染色体。
遗传算法的0-1背包问题(c语言)
基于遗传算法的0-1背包问题的求解摘要:一、前言组合优化问题的求解方法研究已经成为了当前众多科学关注的焦点,这不仅在于其内在的复杂性有着重要的理论价值,同时也在于它们能在现实生活中广泛的应用。
比如资源分配、投资决策、装载设计、公交车调度等一系列的问题都可以归结到组合优化问题中来。
但是,往往由于问题的计算量远远超出了计算机在有效时间内的计算能力,使问题的求解变为异常的困难。
尤其对于NP 完全问题,如何求解其最优解或是近似最优解便成为科学的焦点之一。
遗传算法已经成为组合优化问题的近似最优解的一把钥匙。
它是一种模拟生物进化过程的计算模型,作为一种新的全局优化搜索算法,它以其简单、鲁棒性强、适应并行处理以及应用范围广等特点,奠定了作为21世纪关键智能计算的地位。
背包问题是一个典型的组合优化问题,在计算理论中属于NP-完全问题, 其计算复杂度为)2(O n ,传统上采用动态规划来求解。
设w[i]是经营活动 i 所需要的资源消耗,M 是所能提供的资源总量,p[i]是人们经营活动i 得到的利润或收益,则背包问题就是在资源有限的条件下, 追求总的最大收益的资源有效分配问题。
二、问题描述背包问题( Knapsack Problem)的一般提法是:已知n 个物品的重量(weight )及其价值(或收益profit )分别为0>i w 和0>i p ,背包的容量(contain )假设设为0>i c ,如何选择哪些物品装入背包可以使得在背包的容量约束限制之内所装物品的价值最大?该问题的模型可以表示为下述0/1整数规划模型:目标函数:∑==ni i i n x c x x x f 121),,(max Λ⎪⎩⎪⎨⎧=∈≤∑=),2,1(}1,0{t .s 1n i x p x w i n i i i i Λ (*)式中i x 为0-1决策变量,1=i x 时表示将物品i 装入背包中,0=i x 时则表示不将其装入背包中。
遗传算法求解0-1背包问题(步骤)(精)
遗传算法求解0-1背包问题。
(步骤)#include "iostream.h"#include "iomanip.h"#include "stdlib.h"#include "math.h"#include "time.h"//定义问题的最大规模#define max 100//问题规模,即共有多少个包int packageNum;//每个包的重量int packageWeight[max];//每个包的价值int packageValue[max];//约束,背包的最大容量int limitWeight;//群体的规模int colonySize;//colonyState[i][k] 表示一个染色体//colonyState[1...colonySize][ 0|1 ] 表示一代群体int colonyState[max][2][max];// currAge 表示当前代的编号// (currAge+1)%2 表示下一代的编号int currAge = 0;//个体评价信息表typedef struct tagIndividualMsg{int index;int value;} IndividualMsg;IndividualMsg individualMsg[max];//////////////////////////////////////////////////////////// // 函数声明void printColonyState( int nextAge );//////////////////////////////////////////////////////////// //初始化群体void colonyInit(){int i , j;int w;for( i = 0 ; i < colonySize ; i++ ){//保证找到一个符合约束的染色体w = limitWeight + 1;while( w > limitWeight ){w = 0;for( j = 0 ; j < packageNum && w <= limitWeight ; j++ ){colonyState[i][currAge][j] = rand() % 2;w += packageWeight[j] * colonyState[i][currAge][j];}}}}//对个体进行评价int cmp( const void *a , const void *b ){IndividualMsg *x = (IndividualMsg *)a;IndividualMsg *y = (IndividualMsg *)b;return y->value - x->value;}void individualEstimate(){int i , j;for( i = 0 ; i < colonySize ; i++ ){individualMsg[i].index = i;individualMsg[i].value = 0;for( j = 0 ; j < packageNum ; j++ )individualMsg[i].value += packageValue[j] * colonyState[i][currAge][j]; }qsort( individualMsg , colonySize , sizeof(IndividualMsg) , cmp );}//终止循环的条件bool stopFlag(){//进行n 代进行后停止static int n = 50;if( n-- <= 0 )return true;elsereturn false;}//赌轮选择int gambleChoose(){int wheel[max] = { 0 };int i = colonySize - 1;int choose;wheel[i] = individualMsg[i].value;for( i-- ; i >= 0 ; i-- )wheel[i] = ( individualMsg[i].value + wheel[i+1] ) + colonySize * ( colonySize - i ); int seed = abs( wheel[0] - ( rand() % ( 2 * wheel[0] ) + 1 ) );choose = colonySize - 1;while( seed > wheel[choose] )choose--;// cout<<"----------------------------------------"<<endl;// cout<<"wheel :"<<endl;// for( i = 0 ; i < colonySize ; i++ )// cout<<setw(5)<<wheel[i];// cout<<endl;// cout<<"seed = "<<seed<<endl;// cout<<"choose "<<choose<<endl;return choose;}//交叉void across( int male , int female , int index ){int nextAge = (currAge+1)%2;int i , j , t;int acrossBit = rand() % (packageNum-1) + 1;for( j = 0 ; j < packageNum ; j++ ){colonyState[index][nextAge][j] =colonyState[individualMsg[male].index][currAge][j];colonyState[index+1][nextAge][j] =colonyState[individualMsg[female].index][currAge][j];}for( i = 0 ; i < acrossBit ; i++ ){t = colonyState[index][nextAge][i];colonyState[index][nextAge][i] = colonyState[index+1][nextAge][i];colonyState[index+1][nextAge][j] = t;}}//变异void aberrance( int index ){int seed , nextAge;nextAge = (currAge+1)%2;//只有1/3 的概率发生异变seed = rand() % ( packageNum * 3 );if( seed < packageNum )colonyState[index][nextAge][seed] = ( colonyState[index][nextAge][seed] + 1 ) % 2;}//处理死亡个体void dealDeath(){int i , j;int weight , w;int nextAge = (currAge+1)%2;for( i = 0 ; i < colonySize ; i++ ){weight = 0;for( j = 0 ; j < packageNum ; j++ )weight += packageWeight[j] * colonyState[i][nextAge][j];if( weight > limitWeight ){//随机生成新的个体w = limitWeight + 1;while( w > limitWeight ){w = 0;for( j = 0 ; j < packageNum && w <= limitWeight ; j++ ){colonyState[i][nextAge][j] = rand() % 2;w += packageWeight[j] * colonyState[i][nextAge][j];}}}}printColonyState( nextAge );}//最优个体保护void saveBest(){int i , j;int min , minp , value;int nextAge = ( currAge+1)%2;min = individualMsg[0].value;minp = -1;for( i = 0 ; i < colonySize ; i++ ){value = 0;for( j = 0 ; j < packageNum ; j++ )value += packageValue[j] * colonyState[i][nextAge][j]; if( value <= min ){min = value;minp = i;}}if( minp >= 0 ){for( j = 0 ; j < packageNum ; j++ ){colonyState[minp][nextAge][j] =colonyState[individualMsg[0].index][currAge][j];}}}//////////////////////////////////////////////////////////// void setProblem(){int i;packageNum = 5;int w[] = { 5 , 4 , 3 , 2 , 1 };int v[] = { 8 , 9 , 3 , 1 , 2 };for( i = 0 ; i < packageNum ; i++ ){packageWeight[i] = w[i];packageValue[i] = v[i];}limitWeight = 13;colonySize = 5;}void printProblem(){int i;cout<<"----------------------------------------"<<endl;cout<<"problem state:"<<endl;cout<<"packageNum = "<<packageNum<<endl;cout<<"limitWeight = "<<limitWeight<<endl;cout<<"Weight: ";for( i = 0 ; i < packageNum ; i++ )cout<<setw(3)<<packageWeight[i];cout<<endl;cout<<"Value: ";for( i = 0 ; i < packageNum ; i++ )cout<<setw(3)<<packageValue[i];cout<<endl;}void printColonyState( int k ){cout<<"----------------------------------------"<<endl;cout<<"colonyState-->";if( k == currAge )cout<<"currAge:"<<endl;elsecout<<"next age:"<<endl;int i , j;for( i = 0 ; i < colonySize ; i++ ){for( j = 0 ; j < packageNum ; j++ )cout<<setw(2)<<colonyState[i][k][j];cout<<endl;}}void printIndividualMsg(){int i;cout<<"----------------------------------------"<<endl;cout<<"Individual Msg:"<<endl;for( i = 0 ; i < colonySize ; i++ ){cout<<individualMsg[i].index<<"\t"<<individualMsg[i].value<<endl; }}////////////////////////////////////////////////////////////void main(){srand( (unsigned int)time(NULL) );setProblem();printProblem();//初始群体colonyInit();printColonyState( currAge );while( !stopFlag() ){//评价当前群体individualEstimate();//生成下一代for( int i = 0 ; i < colonySize ; i += 2 ){int male = gambleChoose();int female = gambleChoose();across( male , female , i );aberrance( i );aberrance( i + 1 );}//处理死亡个体dealDeath();//最优个体保护saveBest();//现在的下一代变成下一轮的当前代currAge = ( currAge + 1 ) % 2;//printColonyState( currAge );}//输出问题解individualEstimate();cout<<"近似解:"<<endl;int j , w = 0;cout<<setw(10)<<"Value:";for( j = 0 ; j < packageNum ; j++ )cout<<setw(5)<<packageValue[j];cout<<endl;cout<<setw(10)<<"Weight:";for( j = 0 ; j < packageNum ; j++ ){w += packageWeight[j] * colonyState[individualMsg[0].index][currAge][j]; cout<<setw(5)<<packageWeight[j];}cout<<endl;cout<<setw(10)<<"Choose:";for( j = 0 ; j < packageNum ; j++ )cout<<setw(5)<<colonyState[individualMsg[0].index][currAge][j];cout<<endl;cout<<"limitWeight: "<<limitWeight<<endl;cout<<"总重量: "<<w<<endl;cout<<"总价值: "<<individualMsg[0].value<<endl; }////////////////////////////////////////////////////////////。
遗传算法的01背包问题(c语言)
基于遗传算法的0-1背包问题的求解摘要:一、前言组合优化问题的求解方法研究已经成为了当前众多科学关注的焦点,这不仅在于其内在的复杂性有着重要的理论价值,同时也在于它们能在现实生活中广泛的应用。
比如资源分配、投资决策、装载设计、公交车调度等一系列的问题都可以归结到组合优化问题中来。
但是,往往由于问题的计算量远远超出了计算机在有效时间内的计算能力,使问题的求解变为异常的困难。
尤其对于NP 完全问题,如何求解其最优解或是近似最优解便成为科学的焦点之一。
遗传算法已经成为组合优化问题的近似最优解的一把钥匙。
它是一种模拟生物进化过程的计算模型,作为一种新的全局优化搜索算法,它以其简单、鲁棒性强、适应并行处理以及应用范围广等特点,奠定了作为21世纪关键智能计算的地位。
背包问题是一个典型的组合优化问题,在计算理论中属于NP-完全问题, 其计算复杂度为)2(O n ,传统上采用动态规划来求解。
设w[i]是经营活动 i 所需要的资源消耗,M 是所能提供的资源总量,p[i]是人们经营活动i 得到的利润或收益,则背包问题就是在资源有限的条件下, 追求总的最大收益的资源有效分配问题。
二、问题描述背包问题( Knapsack Problem)的一般提法是:已知n 个物品的重量(weight )及其价值(或收益profit )分别为0>i w 和0>i p ,背包的容量(contain )假设设为0>i c ,如何选择哪些物品装入背包可以使得在背包的容量约束限制之内所装物品的价值最大?该问题的模型可以表示为下述0/1整数规划模型:目标函数:∑==ni i i n x c x x x f 121),,(max Λ⎪⎩⎪⎨⎧=∈≤∑=),2,1(}1,0{t .s 1n i x p x w i n i i i i Λ (*) 式中i x 为0-1决策变量,1=i x 时表示将物品i 装入背包中,0=i x 时则表示不将其装入背包中。
遗传算法的0-1背包问题(c语言)
基于遗传算法得0—1背包问题得求解摘要:一、前言组合优化问题得求解方法研究已经成为了当前众多科学关注得焦点,这不仅在于其内在得复杂性有着重要得理论价值,同时也在于它们能在现实生活中广泛得应用。
比如资源分配、投资决策、装载设计、公交车调度等一系列得问题都可以归结到组合优化问题中来、但就是,往往由于问题得计算量远远超出了计算机在有效时间内得计算能力,使问题得求解变为异常得困难。
尤其对于NP完全问题,如何求解其最优解或就是近似最优解便成为科学得焦点之一、遗传算法已经成为组合优化问题得近似最优解得一把钥匙。
它就是一种模拟生物进化过程得计算模型,作为一种新得全局优化搜索算法,它以其简单、鲁棒性强、适应并行处理以及应用范围广等特点,奠定了作为21世纪关键智能计算得地位。
背包问题就是一个典型得组合优化问题,在计算理论中属于NP-完全问题,其计算复杂度为,传统上采用动态规划来求解。
设w[i]就是经营活动i 所需要得资源消耗,M就是所能提供得资源总量,p[i]就是人们经营活动i得到得利润或收益,则背包问题就就是在资源有限得条件下,追求总得最大收益得资源有效分配问题。
二、问题描述背包问题( Knapsack Problem)得一般提法就是:已知n个物品得重量(wei ght)及其价值(或收益profit)分别为与,背包得容量(contain)假设设为,如何选择哪些物品装入背包可以使得在背包得容量约束限制之内所装物品得价值最大?该问题得模型可以表示为下述0/1整数规划模型:目标函数:(*)式中为0-1决策变量,时表示将物品装入背包中,时则表示不将其装入背包中。
三、求解背包问题得一般方法解决背包问题一般就是采取动态规划、递归回溯法与贪心方法、动态规划可以把困难得多阶段决策变换为一系列相互联系比较容易得单阶段问题、对于背包问题可以对子过程用枚举法求解,而且约束条件越多,决策得搜索范围越小,求解也越容易。
它得主要缺点就是用数值方法求解时会随着状态变量得个数呈指数级得增长,往往对于求解背包问题得实际问题就是不现实得。
遗传算法求解01背包问题
遗传算法求解01背包问题一、问题描述01背包问题属于组合优化问题的一个例子,求解01背包问题的过程可以被视作在很多可行解当中求解一个最优解。
01背包问题的一般描述如下:给定n个物品和一个背包,物品i的重量为W i,其价值为V i,背包的容量为C。
选择合适的物品装入背包,使得背包中装入的物品的总价值最大。
注意的一点是,背包内的物品的重量之和不能大于背包的容量C。
在选择装入背包的物品时,对每种物品i只有两种选择:装入背包或者不装入背包,即只能将物品i装入背包一次。
称此类问题为0/1背包问题。
01背包问题是NP问题,传统的解决方法有动态规划法、分支界限法、回溯法等等。
传统的方法不能有效地解决01背包问题。
遗传算法(Genetic Algorithms)则是一种适合于在大量的可行解中搜索最优(或次优)解的有效算法。
二、遗传算法1、遗传算法的基本思想遗传算法的搜索从一个被称作种群的候选解集开始,新的种群由旧的种群中产生以期得到更好的种群。
从旧种群中按照解的适应度来选择解以产生新的解;适应度越大,解被选择生成后代的机率也越大。
这个从已有种群中选择双亲并产生后代的迭代过程持续到遗传算法的停止条件满足为止。
2、遗传算法的基本元素。
遗传算法由以下几个原素组成:由染色体组成的种群,根据适应度进行选择以及交叉产生后代。
三、用遗传算法求解01背包问题1、01背包问题中染色体的表示。
用向量X来表示染色体,X = {x1,x2,……,x n}。
,x i∈{0,1},x i=1表示物品i装入了背包,x i =0表示物品i未装入背包。
每个染色体对应其当前装入背包的物品的总价值和总重量。
背包中物品的中价值代表了该物品的适应度。
程序中定义了这样的一个结构来表示染色体:typedef struct{int Weight; //染色体代表的物品的总重量int Fitness; //染色体代表的物品的价值(适应度)int Gene[NUMG]; //用元素取值于定义域{0,1}的数组表示染色体。
遗传蚁群算法解决背包问题
算法策略
(4)Allowed中物品j被选择的概率(步骤6(3))为:
其中,tj为物品j上的信息素浓度,初始信息浓度 tj相等,本文设 tj=1/sum(P)(P为物品的价 值集),qj为物品 j 的价值重量比。
(5)选择操作(步骤7)采用排序法,所有蚂蚁和上代中的前k个个体共同参与排 序。遗传算法和蚁群算法均采用0、1 编码和统一的信息素更新公式:
结束
Thank you !
改进型遗传蚁群混合算法求解 0/1背包问题
报告人:宋玲 地 点:计算机院软工实训室 时 间:2013年11月15日
研究背景
背包问题(Knapsack Problems)是运筹学中的一个典型的优化难
题,对背包问题的研究具有极其重要的理论和现实意义。实际生活中, 资源分配、投资决策、装载问题、网络资源分配等问题都可归纳为背包 问题。目前,已经出现许多种求解背包问题的优化算法。其中遗传算法 是一种基于自然选择和群体遗传机理的搜索算法,模拟了自然选择和自 然遗传过程中的繁殖、杂交和突变现象。它属于随机搜索算法,具有较 强的全局搜索能力,但遗传算法中的个体对于每次的选择不存在反馈信 息,因此遗传算法的收敛速度较慢,而且优化精度不高。蚁群算法在求 解 0/1背包问题时,主要通过物品上的信息素进行选择,一个物品上的 信息素越高,被选择的概率就越大。蚁群算法采用正反馈机制,能够快 速地收敛到问题的局部最优解,但存在全局搜索能力较低、搜索时间较 长等缺点。由于两种算法各有利弊,近年来,许多学者致力于两种算法 的混合研究。本文提出了一种基于两者新的混合方式的算法,来求解 0/1背包问题。
人工智能之遗传算法求解01背包问题实验报告
人工智能之遗传算法求解0/1背包问题实验报告Pb03000982 王皓棉一、问题描述:背包问题是著名的NP完备类困难问题, 在网络资源分配中有着广泛的应用,已经有很多人运用了各种不同的传统优化算法来解决这一问题,这些方法在求解较大规模的背包问题时,都存在着计算量大,迭代时间长的弱点。
而将遗传算法应用到背包问题的求解,则克服了传统优化方法的缺点,遗传算法是借助了大自然的演化过程,是多线索而非单线索的全局优化方法,采用的是种群和随机搜索机制。
遗传算法(GA)是一类借鉴生物界自然选择和自然遗传机制的随机化的搜索算法,由美国J.Holland教授提出,其主要特点是群体搜索策略、群体中个体之间的信息交换和搜索不依赖于梯度信息。
因此它尤其适用于处理传统搜索方法难于解决的复杂和非线性问题,可广泛应用于组合优化,机器学习,自适应控制,规划设计和人工生命领域。
GA是一种群体型操作,该操作以群体中的所有个体为对象。
选择,交叉和变异是遗传算法的三个主要算子,他们构成了遗传算法的主要操作,使遗传算法具有了其它传统方法所没有的特性。
遗传算法中包含了如下五个基本要素:1 .参数编码,2.初始群体的设置,3.适应度函数的设计, 4.遗传操作设计,5.控制参数设定,这个五个要素构成可遗传算法的核心内容。
遗传算法的搜索能力是由选择算子和交叉算子决定,变异算子则保证了算法能够搜索到问题空间的每一个点,从而使其具有搜索全局最优的能力.而遗传算法的高效性和强壮性可由Holland提出的模式定理和隐式并行性得以解释。
二、实验目的:通过本实验,可以深入理解遗传算法,以及遗传算法对解决NP问题的作用。
三、算法设计:1、确定种群规模M、惩罚系数 、杂交概率c p、变异概率m P、染色体长度n及最大max.进化代数genx=1表2、采用二进制n维解矢量X作为解空间参数的遗传编码,串T的长度等于n,ix=0表示不装入背包。
例如X={0,1,0,1,0,0,1}表示第2,4,7示该物件装入背包,i这三个物件被选入包中。
“遗传算法”解决“背包问题”
“遗传算法”解决“背包问题”遗传算法基本思想:1) ⼀个种群有多个个体,每个个体有染⾊体和对应的基因为了繁殖进⾏:2) 选择:在残酷的世界中,适者⽣存,优胜略汰。
3) 重组:染⾊体交叉,基因重组4) 突变:染⾊体上的基因⼩概率的突变(⼀般给⼩数点后两位)背包问题:背包只能容得下⼀定重量b的物品,物品有m种,每种物品有⾃⼰的重量w(i)和价值v(i)(0<i<=m),从这些物品中选择装⼊背包,是背包不超过重量b,但价值⼜要最⼤。
运⽤动态规划,分⽀限界都可以达到效果,但不佳。
我⽤遗传算法解决:⼀般⼈有多条染⾊体,但对于背包问题,⼀个解我们将看成⼀个个体,所以,⼀个个体只有⼀个染⾊体,⼀个染⾊体对应多个基因。
如:100101010100111 表⽰装⼊背包的可能解。
(具体情况具体分析)遗传所做准备:1) ⽤0表⽰“不选择装⼊”,1表⽰“装⼊”,形成⼀条基因链;100101010100111则表⽰“15种物品”装⼊或不装⼊背包的可能解。
------- 此处⽤chrom[]存放基因,代表染⾊体2) ⼀个基因对应⼀个个体。
------- 此处⽤Population类或结构体声明其含有chrom[]等信息3) 可能的解有很多,构成⼀个种群。
------- ⽤Population类定义⼀个数组代表个体构成的种群newPop[]:存放新⽣代,oldPop[]:存放上⼀代4) 适应度:适应度和⽬标函数是正相关的,所以需要物品价值和重量。
------- fitness,weight包含在Population类中最⼤适应度:maxFitness,最⼩适应度:minFitness,总适应度:sumFitness,(帮助求突变和交叉的染⾊体)平均适应度:avgFitness遗传算法的函数:基本:1) InitPop() 初始化个体,使每个个体都有基因组2) Statistics(*pop) 计算适应度(最⼤,最⼩,总的,平均的)3) Selection(*pop) 通过选择种群中符合要求的⽗母去繁殖新代,返回这对⽗母的位置4) crossover(*parent1,*parent2,pos) 传⼊要改的个体位置,随机产⽣交叉位置,⽤优良⽗母繁殖优良后代并替代传⼊个体位置5) mutation(i) i为基因组基因的位置,逐个基因看是否要变异6) generation() 对个体进⾏判断,若不符合要求,进⾏选择,重组,突变。
智能控制作业遗传算法求解背包问题
智能控制作业遗传算法求解背包问题智能控制遗传算法求解背包问题——16组遗传算法求解背包问题摘要:遗传算法是在分析遗传个体进化机制基础上提出的一种新型优化算法。
本论文根据0-1 背包问题的特点,提出用于求该问题的遗传算法及相关的解决方案,阐明算法的具体实现过程。
通过对其他文献中仿真实例的计算和结果比较,表明应用该算法求解背包问题取得了良好的效果。
该算法同样可以应用于其他组合优化题。
关键词:背包问题;遗传算法一.概述背包问题(knapsack problem) 是运筹学中一个典型的优化难题,有着广泛的实际应用背景,如管理中的资源分配、投资决策、预算控制等问题,并且经常作为其他问题的子问题被研究。
研究背包问题的求解算法在理论上和实践中都具有一定的意义。
从计算复杂性理论来看,背包问题是个NP 完全问题,该问题的求解方法主要有启发式算法,如贪心算法、遗传算法、粒子群算法。
以遗传算法为代表的生物进化算法建立在达尔文自然选择学说的基础上,是对生物进化过程的模拟,是人们对从自然演化过程中抽象出的概念、原则和机制的类比应用,被广泛用于解决复杂的计算问题。
其主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具有内在的隐并行性和更好的全局寻优能力;采用概率化的寻优方法,能自动获取和指导优化的搜索空间,自适应地调整搜索方向,不需要确定的规则。
遗传算法的这些性质,已被人们广泛地应用于组合优化、机器学习、信号处理、自适应控制和人工生命等领域。
它是现代有关智能计算中的关键技术。
本文在分析遗传算法的基础上,提出了将贪婪修复方法与遗传算法相结合,构成混和遗传算法,并应用于求解经典背包问题。
它是可以解决复杂问题的新方法。
本论文系统的介绍背包问题的遗传算法解决方案。
二.背包问题的数学模型背包问题的定义:我们有n 种物品,物品j 的重量为wj ,价格为pj 。
我们假定所有物品的重量和价格都是非负的。
背包所能承受的最大重量为W 。
基于遗传算法求解背包问题【精品毕业设计】(完整版)
毕业设计(论文)基于遗传算法求解背包问题院别专业名称班级学号学生姓名指导教师2012年6月15日基于遗传算法求解背包问题摘要背包问题(Knapsack problem)是一种组合优化的NP完全问题,本文首先介绍了基本遗传算法的基本原理、特点及其基本实现技术,接着针对背包问题,论述了遗传算法在编码表示和遗传算子(包括选择算子、交叉算子变异算子这三种算子)等方面的应用情况。
并且结合背包问题实例,给出了具体的编码方法,运行参数,群体大小,最大迭代次数,以及合适的遗传算子。
最后,简单说明了遗传算法在求解背包问题中的应用并对遗传算法解决背包问题的前景提出了展望。
关键词:背包问题,遗传算法,遗传算子Genetic Algorithm for KPAuthor:Yang DongTutor:Kong ZhiAbstractKP (Knapsack Problem) is a combinatorial optimization of NP - complete problem. The primary knowledge, characteristics and the basic techniques of GA are introduced firstly. The encoding model and genetic operators (including selection operation, crossover operation and mutation operation) solving KP are discussed secondly. Combined with examples of knapsack problem, we have given the specific encoding method, operating parameters, popsize, maxgeneration, and suitable genetic operator. At last, the application of genetic algorithm is simple presented, and the prospect for the future of genetic algorithm in solving KP has been given.Key Words: KP, genetic algorithm, genetic operators目录1绪论 (III)1.1 引言 (1)1.2 背包问题概述 (1)1.2.1 背包问题的描述 (2)1.2.2 研究背包问题的意义 (9)1.3 遗传算法 (10)1.3.1 遗传算法概述 (10)1.3.2 遗传算法的特点 (10)1.3.3 遗传算法的应用领域 (11)2遗传算法的基本原理 (13)2.1 基本流程 (14)2.2 编码 (14)2.3 适应度函数 (15)2.4 遗传算子 (15)2.4.1 选择算子 (15)2.4.2 交叉算子 (17)2.4.3 变异算子 (17)2.5 参数控制 (18)2.5.1 群体规模 (18)2.5.2 交叉概率 (18)2.5.3 变异概率 (18)2.6 算法结束条件控制 (19)3求解实现背包问题的遗传算法 (20)3.1 0_1背包问题中染色体的表示 (20)3.2 算法求解01背包问题时用到的参数 (20)3.3 选择操作 (20)3.4 交叉操作 (21)3.5 精英策略 (22)3.6 变异操作 (22)3.7 代际更新 (23)3.8 算法的终止 (23)3.9 仿真结果与测试 (24)3.9.1 不同交叉概率下所的测试结果 (25)3.9.2 极端数据对结果的影响 (27)3.9.3 仿真结果总结 (29)结论 (31)致谢 (32)参考文献 (33)附录 (34)1绪论1.1引言现代科学理论研究与实践中存在着大量与优化、自适应相关的问题,但除了一些简单的情况之外,人们对于大型复杂系统的优化和自适应问题仍然无能为力。
一种求解背包问题的混合遗传微粒群算法
一种求解背包问题的混合遗传微粒群算法中国混合遗传微粒群算法(GABC)是一种用于解决复杂优化问题的混合遗传算法。
它在遗传算法中引入了粒子群优化,采用多实体群体管理和多种解决思路,在解决复杂问题能力和全局搜索能力上均具有优势。
GABC算法可用于求解背包问题,也就是说在给定的物品和背包容量的前提下,如何以最大的利润形式选择物品,使得背包里的一组物品的价值总和最大化。
GABC算法的对象是适应度函数,它是通过比较解决方案的利润总和,并找出最优的解决方案,以实现物品的最大利用率和最大利润的优化目标。
1)GABC算法原理GABC算法采用遗传和粒子群优化算法的特点,结合有效搜索和群体管理,设计出一个联合算法,用于求解复杂优化问题,包括背包问题。
(1)遗传算法:采用遗传算法中常用的算子,如交叉、变异等,利用群体的发展趋势,预估物品的权值。
当前一代群体的表现决定下一代群体成员的品质,可以实现物品的迅速搜索,以确定最优解。
(2)粒子群优化:采用粒子群优化算法,以经验法则、随机规则和多搜索算法为标准。
粒子群优化以概率法确定物品的搜索范围,将群体实体单独根据其适应与目标值及历史最佳重排,使成员具有更强的搜索能力和全局搜索能力。
2) GABC算法的应用GABC算法可以用于求解复杂的优化问题,包括背包问题等。
在求解背包问题时,GABC结合遗传和粒子群优化技术,通过前述的步骤实现了一种简单而有效的搜索思想,可根据条件快速找出最优物品组合。
GABC算法可以有效处理复杂优化问题,充分利用遗传算法和粒子群优化分别具备的有效解决思路,改善算法组件之间的协作,有效提升了搜索能力和精度,并可以根据具体情况,引入邻域搜索等新方法,更高效地求解复杂优化问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
遗传算法求解背包问题信管专业李鹏 201101002044一、遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法,是从代表问题可能潜在的解集的一个种群(population)开始的,而一个种群则由经过基因(gene)编码的一定数目的个体(individual)组成。
在每一代,根据问题域中个体的适应度(fitness)大小选择(selection)个体,并借助于自然遗传学的遗传算子(genetic operators)进行组合交叉(crossover)和变异(mutation),产生出代表新的解集的种群。
二、背包问题描述背包问题是一个典型的组合优化问题,在计算理论中属于NP完全问题,主要应用于管理中的资源分配,资金预算,投资决策、装载问题的建模。
传统“0/1”背包问题可以描述为:把具有一定体积和价值的n件不同种类物品放到一个有限容量的背包里,使得背包中物品的价值总量最大。
三、数学模型背包问题可以描述如下:假设有n个物体,其重量用表示,价值用表示,背包的最大容量为b。
这里和b都大于0。
问题是要求背包所装的物体的总价值最大。
背包问题的数学模型描述如下:(1)(2)(3)约束条件(3)中表示物体i被选入背包,反之,表示物体i没有被选入背包。
约束条件(2)表示背包的容量约束。
四、使用遗传算法解决“0-1背包问题”的思路:0-1背包的解可以编码为一串0-1字符串(0:不取,1:取);首先,随机产生M个0-1字符串,然后评价这些0-1字符串作为0-1背包问题的解的优劣;然后,随机选择一些字符串通过交叉、突变等操作产生下一代的M个字符串,而且较优的解被选中的概率要比较高。
这样经过G代的进化后就可能会产生出0-1背包问题的一个“近似最优解”。
五、程序整体流程(1)读取存取包的限种、商品的重要和价值的TXT文件;(2)初始化种群;(3)计算群体上每个个体的适应度值(Fitness) ;(4)评估适应度,对当前群体P(t)中每个个体Pi计算其适应度F(Pi),适应度表示了该个体的性能好坏;(5)依照Pc选择个体进行交叉操作;(6)仿照Pm对繁殖个体进行变异操作(7)没有满足某种停止条件,则转第3步,否则进入8 ;(8)输出种群中适应度值最优的个体。
六、代码function Main()%定义全局变量global VariableNum POPSIZE MaxGens PXOVER PMutationVariableNum=3 %变量个数POPSIZE=50 %种群大小MaxGens=1000 %种群代数PXOVER=0.8 %交叉概率PMutation=0.2 %变异概率%读取数据文件load E:\现代优化算法\遗传算法\bound.txtVarBound=bound(:,1:2);global Pop newPopPop=zeros(POPSIZE+1,VariableNum);newPop=zeros(POPSIZE+1,VariableNum);%初始化种群for i=1:POPSIZEfor j=1:VariableNumPop(i,j)=VarBound(j,1)+rand()*(VarBound(j,2)-VarBound(j,1)); endend%计算适应值fitnessList=zeros(POPSIZE,1);for i=1:POPSIZEfitnessList(i,1)=fitness(Pop(i,1:VariableNum));end%保存最好值和最坏值Best=zeros(1,VariableNum+1);Worst=zeros(1,VariableNum+1);maxvalue=max(fitnessList);indexMax=find(fitnessList==maxvalue,1,'first');Best(1,1:VariableNum)=Pop(indexMax,1:VariableNum);Best(1,VariableNum+1)=maxvalue;minvalue=min(fitnessList);indexMin=find(fitnessList==minvalue,1,'first');Worst(1,1:VariableNum)=Pop(indexMin,1:VariableNum);Worst(1,VariableNum+1)=minvalue;genetation=1;while genetation<MaxGens%计算适应度区间sumfit=sum(abs(fitnessList));relativeFitness=zeros(POPSIZE,1);relativeFitness=abs(fitnessList)/sumfit;for i=2:POPSIZErelativeFitness(i)=relativeFitness(i-1)+relativeFitness(i); end%选择操作newPop=Select(Pop,relativeFitness);%交叉操作newPop=Xcross(newPop,VariableNum,PXOVER);%变异操作newPop=Mutation(newPop,VariableNum,PMutation,VarBound);%计算新种群适应值for i=1:POPSIZEfitnessList(i,1)=fitness(newPop(i,1:VariableNum));end%保存最好值和替换最坏值maxvalue=max(fitnessList);indexMax=find(fitnessList==maxvalue,1,'first');minvalue=min(fitnessList);indexMin=find(fitnessList==minvalue,1,'first');if Best<maxvalueBest(1,1:VariableNum)=newPop(indexMax,1:VariableNum); Best(1,VariableNum+1)=maxvalue;elsenewPop(indexMin,1:VariableNum)=Best(1,1:VariableNum); fitnessList(indexMin,1)=Best(1,VariableNum+1);end%用子代替换父代Pop=newPop;genetation=genetation+1;endBest=========================================================%选择操作function newPop=Select(Pop,Rfitness)for i=1:length(Rfitness)r=rand();index=1;for j=1:length(Rfitness)if r<=Rfitness(j,1)index=j;break;endendnewPop(i,:)=Pop(index,:);end======================================%交叉操作function newPop=Xcross(Pop,VariableNUM,CrossRate)point=1;sizePop=length(Pop);for i=0:sizePop/2Xrate=rand();if Xrate<CrossRate %如果交叉first_index=round(rand()*(sizePop-2)+1);second_index=round(rand()*(sizePop-2)+1);while first_index==second_index %排除两个个体一样的情况 second_index=round(rand()*(sizePop-2)+1);endif VariableNUM>1if VariableNUM==2point=1;elsepoint=round(rand()*(VariableNUM-2)+1);endtempOne=zeros(1,point);tempOne(1,1:point)=Pop(first_index,1:point);Pop(first_index,1:point)=Pop(second_index,1:point); Pop(second_index,1:point)=tempOne(1,1:point);endendendnewPop=zeros(size(Pop),1);newPop=Pop;====================================================%变异操作function newPop=Mutation(Pop,VariableNUM,MutationRate,bound) point=1;sizePop=length(Pop);for i=1:sizePopfor j=1:VariableNUMMrate=rand();if Mrate<MutationRate %如果发生变异Pop(i,j)= rand()*(bound(j,2)-bound(j,1))+ bound(j,1);endendendnewPop=zeros(size(Pop),1);newPop=Pop;=================================================%适应值函数或目标函数%函数 x1^2-x1*x2+x3function value=fitness(varargin)n=varargin{1,1};value=n(1,1)^2-n(1,1)*n(1,2)+n(1,3);七、结论遗传算法在处理背包问题时借助了大自然的演化过程,采用的是种群和随机搜索机制,它是一种多线索而非单线索的全局优化方法,能克服传统优化方法的缺点。