hdu 2602 Bone Collector【遗传算法解01背包】
来源:互联网 发布:u盘修复软件 编辑:程序博客网 时间:2024/06/06 18:53
hdu 2602 Bone Collector
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602
题目分析:01背包水无坑,由于本篇是用GA解,学习ACM中01背包问题解法的同学请移步 原链接 。
对遗传算法的认识:对生物界遗传过程进行模拟来解决问题的一种算法,大体流程如下:遗传(指定generation数){计算适应度->选择->交叉->变异}。实际设计算法时可按需略作调整。
声明:博主提交oj没过,全是WA。
以下是C++code
#include<stdio.h>#include<stdlib.h>#include<time.h>#include<algorithm>#define fineN 50using namespace std;/** 每一组解是一个1*n的数组,每一位表示第i个物体0不放、1放入 */int pop_size=890,maxgen=800,pop_pointer=890;//种群最大规模50、迭代次数30、种群当前规模 double te=0.2;//优势种群前20% int n,v,val[1009],vol[1009];class Individual{ public: int fitness,load; short*strategy; bool overload; Individual(){} Individual(short*s) { //memcpy(strategy,s,n*sizeof(short)); strategy=new short(1009); for(int i=0;i<n;i++) { strategy[i]=s[i]; } load=fitness=0; overload=false; cal_fitnld(); } void cal_fitnld() {//计算fitness,多出的load按fineN倍惩罚 fitness=load=0; for(int i=0;i<n;i++) { fitness+=strategy[i]?val[i]:0; load+=strategy[i]?vol[i]:0; //printf("第%d个%s\n",i,strategy[i]?"装":"不装"); } if(load>v) { //printf("超载:load=%d, v=%d\n",load,v); fitness-=(load-v)*fineN; overload=true; } } /*void mutation() { if((rand()%10)<2)//判断是否变 { int flag=rand()%n; if(strategy[flag]==0) {//计算适应度 fitness+=val[flag]; load+=vol[flag]; } strategy[flag]=1-strategy[flag];//变 } }*/};int cmp(Individual a,Individual b){ return a.fitness>b.fitness;}/*short*shtcpy(short*b){ short a[100]; for(int i=0;i<n;i++) { a[i]=b[i]; } return a;}char*chrom2str(short*a){ char ret[100]; for(int i=0;i<n;i++) { ret[i]=a[i]+'0'; } ret[n]=0; return ret;}*/int main(){ Individual inque[1009]; srand((unsigned)time(NULL)); int t; short s1[1009],s2[1009]; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&v); for(int i=0;i<n;i++) { scanf("%d",val+i); } for(int i=0;i<n;i++) { scanf("%d",vol+i); } //初始化种群 for(int i=0;i<pop_size;i++) { for(int j=0;j<n;j++) { s1[j]=rand()%2; } inque[i]=*(new Individual(s1)); } //进化开始 for(int i=0;i<maxgen;i++) { //选择==丢弃劣势种群 pop_pointer=pop_size*te; //交叉变异 while(pop_pointer<pop_size) { if(rand()%2)//交叉 {//交叉概率50%,其中10%是两位交叉 int fc=rand()%pop_pointer,sc=rand()%pop_pointer;//first or second chrom int place=rand()%n; /*for(int j=0;j<n;j++) { s1[j]=inque[fc].strategy[j]; s2[j]=inque[sc].strategy[j]; }*/ memcpy(s1,inque[fc].strategy,n*sizeof(short)); memcpy(s2,inque[sc].strategy,n*sizeof(short)); //s1=shtcpy(inque[fc].strategy); //s2=shtcpy(inque[sc].strategy); if(inque[fc].strategy[place]!=inque[sc].strategy[place]) { s1[place]=1-s1[place]; s2[place]=1-s2[place]; } if(rand()%10==0) { place=rand()%n; s1[place]=1-s1[place]; s2[place]=1-s2[place]; } inque[pop_pointer++]=*(new Individual(s1)); inque[pop_pointer++]=*(new Individual(s2)); //printf("交叉:pop_pointer=%d\n",pop_pointer); } else//变异 { int chrom=rand()%pop_pointer,place=rand()%n; //printf("copy前:s1=%s,chrom=%s\n",chrom2str(s1),chrom2str(inque[chrom].strategy)); //s1=shtcpy(inque[chrom].strategy); /*for(int j=0;j<n;j++) { s1[j]=inque[chrom].strategy[j]; }*/ memcpy(s1,inque[chrom].strategy,n*sizeof(short)); //printf("copy后:s1=%s,chrom=%s\n",chrom2str(s1),chrom2str(inque[chrom].strategy)); s1[place]=1-s1[place]; //printf("变异后:s1=%s,chrom=%s\n",chrom2str(s1),chrom2str(inque[chrom].strategy)); inque[pop_pointer++]=*(new Individual(s1));//变 } } sort(inque,inque+pop_size,cmp); /*printf("\nfit list:"); for(int j=0;j<pop_size;j++) { printf("\t%d",inque[j].fitness); } putchar('\n');*/ } /*printf("\n结果:fitness1=%d\n",inque[0].fitness); for(int i=0;i<n;i++) { printf("%c\n",inque[0].strategy[i]+'0'); }*/ printf("%d\n",inque[0].fitness); }//断点设置 return 0;}
C++……,请运行出错的同学在return 0;上一行标记处设置断点调试运行,别问我为什么,我也不知道。如有大神路过还请不吝赐教。
写这些东西果断还是应该用python的嘛
# coding:utf-8import copyimport randomclass GApackageSolution: #此类解决用GA解背包问题 maxgen=35 #最大代数 pop_size=120 #种群规模 n=0 #物品总数 v=0 #背包容量 te=0.2 #top elite占比 population=[] #种群 class Individual: fineN=18 #惩罚系数,用于超重惩罚 val=[] #物品价值 vol=[] #物品体积 def __init__(self,c): self.chrom=copy.deepcopy(c) self.fitness=0 self.load=0 #print len(c),len(self.val),len(self.vol) for i in range(len(c)): self.fitness+=self.val[i]if c[i]==1 else 0 self.load+=self.vol[i]if c[i]==1 else 0 pass if self.load>v:self.fitness-=self.fineN*(self.load-v) return def do_cross(self,c1,c2,cp1,cp2,place,pop): if place==0: chrom1=[cp2]+pop[c1].chrom[1:] chrom2=[cp1]+pop[c2].chrom[1:] pass else: chrom1=pop[c1].chrom[:place-1]+[cp2]+pop[c1].chrom[place:] chrom2=pop[c2].chrom[:place-1]+[cp1]+pop[c2].chrom[place:] pass return chrom1,chrom2 def cross(self): #print 'cross called' pop=self.population c1=random.randint(0,len(pop)-1) c2=random.randint(0,len(pop)-1) place=random.randint(0,n-1) cp1=pop[c1].chrom[place] cp2=pop[c2].chrom[place] #print 'chrom1=',pop[c1].chrom,'chrom2=',pop[c2].chrom,'place=',place #print pop[c1].chrom[:place-1],[cp2],pop[c1].chrom[place:] chrom1,chrom2=self.do_cross(c1,c2,cp1,cp2,place,pop) if random.randint(0,2)==0: place=random.randint(0,n-1) cp1=chrom1[place] cp2=chrom2[place] chrom1,chrom2=self.do_cross(c1,c2,cp1,cp2,place,pop) #print len(chrom1),len(chrom2) pass #print chrom1,chrom2 self.population.append(self.Individual(chrom1)) self.population.append(self.Individual(chrom2)) return def do_mutation(self,ochrom,place): if place==0: xchrom=[1-ochrom[place]]+ochrom[1:] pass else: xchrom=ochrom[:place-1]+[1-ochrom[place]]+ochrom[place:] pass return xchrom def mutation(self): #print 'mutation called' pop=self.population c=random.randint(0,len(pop)-1) place=random.randint(0,n-1) ochrom=pop[c].chrom #original chrom原始染色体 #print 'ochrom=',ochrom,'place=',place #print ochrom[:place-1],[1-ochrom[place]],ochrom[place:] xchrom=self.do_mutation(ochrom,place) #print xchrom self.population.append(self.Individual(xchrom)) return def run(self): for k in range(self.maxgen): self.population=self.population[:int(self.te*self.pop_size)] for i in range(len(self.population)): print 'strategy:',i,self.population[i].chrom,'fitness=',\ self.population[i].fitness #剔除劣势种群 while len(self.population)<=self.pop_size:#交叉变异补回来 if(random.randint(0,1)==0): #print 'mutation call' self.mutation() pass else: #print 'cross call' self.cross() pass pass self.population.sort(lambda x,y:cmp(y.fitness,x.fitness)) pass ret='strategy:' for i in range(self.n): ret=ret+str(self.population[0].chrom[i]) return ret+'\nfitness:'+str(self.population[0].fitness) def __init__(self,n,v,val,vol): self.n=n self.v=v self.Individual.val=val self.Individual.vol=vol for i in range(self.pop_size): c=[] for j in range(n): c.append(random.randint(0,1)) self.population.append(self.Individual(c)) #print c pass returnif __name__=='__main__': print 'Which one would you like to test?' filenum=raw_input('Please input a number between 0-9.\n') fp=open('beibao'+filenum+'.in') line=fp.readline() line=line.strip() line=line.split(' ') print line v=int(line[0]) n=int(line[1]) val=[] vol=[] for line in fp.readlines(): line=line.strip() line=line.split() vol.append(int(line[0])) val.append(int(line[1])) pass obj=GApackageSolution(n,v,val,vol) print obj.run()
前几天系统崩溃,代码没了,这一版是后写的,所以注释略少,见谅
注意,不要用hdu 2602的输入,python版的输入格式与那个不符,我已经上传了数据压缩包,地址如下。输入就将那个压缩包里的文件解压到程序文件旁,运行python程序即可。
01背包测试数据地址
暂时就这样。
0 0
- hdu 2602 Bone Collector【遗传算法解01背包】
- hdu 2602 (01 背包)Bone Collector
- hdu 2602 Bone Collector 01背包
- hdu 2602 Bone Collector 01背包
- hdu 2602 Bone Collector (01背包)
- hdu 2602 Bone Collector【01背包】
- hdu 2602 Bone Collector 简单01背包
- hdu 2602 Bone Collector(01背包)
- hdu 2602 Bone Collector (01背包)
- HDU 2602 Bone Collector(裸01背包)
- HDU 2602 Bone Collector( 01背包 )
- HDU 2602 Bone Collector(01背包)
- hdu 2602 Bone Collector 01背包
- HDU 2602 Bone collector 01背包
- hdu 2602 Bone Collector (01背包 )
- hdu 2602 Bone Collector (01背包)
- HDU 2602 Bone Collector (01背包)
- HDU--2602 -- Bone Collector [01背包]
- 利用OpenCV创建自己的Rect类
- 了解Android资源(上)
- 正则表达式抽取网页内容
- postgresql双机热备、高可用方案(采用pacemaker+corosync实现)
- 在HTML网页上打印需要的内容,JS代码
- hdu 2602 Bone Collector【遗传算法解01背包】
- 机器学习笔记(二)
- 详细讲解transform,一看就懂了!(转)
- 排序算法
- 了解Android资源(下)
- java基础(五),接口
- HM编码器代码阅读(11)——CU的初始化
- tomcat访问主页报404
- Java设计模式(三) Visitor(访问者)模式及多分派场景应用