hdu 2602 Bone Collector
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602
题目分析:01背包水无坑,由于本篇是用GA解,学习ACM中01背包问题解法的同学请移步 原链接 。
对遗传算法的认识:对生物界遗传过程进行模拟来解决问题的一种算法,大体流程如下:遗传(指定generation数){计算适应度->选择->交叉->变异}。实际设计算法时可按需略作调整。
声明:博主提交oj没过,全是WA。
以下是C++code
#include
#include
#include
#include
#define fineN 50
using 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;iv)
{
//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
写这些东西果断还是应该用python的嘛
# coding:utf-8
import copy
import random
class 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
return
if __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背包测试数据地址
暂时就这样。