遗传算法r
1. 遗传算法求解背包问题的程序
1楼的不是遗传算法吧!
刚好做过这个遗传算法解背包问题的论文,给你回答啦~~独家哦,分数要给偶~~
1、程序开发环境
开发环境:Visual C++6.0 (把Fortran程序改为VC)
操作系统:Windows 2003 Professional
2、程序性能对比
运行时间与加速比(如表1所示)
进程数p(个) 1 2 4
运行时间t(秒) 129s 78s 38s
加速比s 1.65 3.38
表1、运行时间与加速比
3、程序运行结果:
实例数据:
假设物体的重量Weight、物体的收益Profit和背包的容量Contain 分别为:
Weight={ 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 }
Profit={ 220,208,198,192,180, 180,165,162,160,158,
155,130,125,122,120 , 118,115,110,105,101,
100,100,98, 96, 95, 90, 88, 82, 80, 77 ,
75, 73, 72, 70, 69, 66, 65, 63, 60, 58,
56, 50, 30, 20, 15, 10, 8, 5, 3, 1}
Contain=1000,
如何选择哪些物品装入该背包可使得在背包的容量约束限制之内所装物品的总价值最大?
传统的算法(动态规划、递归回溯法和贪心算法所得结果:
总价值为3077 , 总重量为999。
2001年张铃,张钹教授在计算机学报上发表的《佳点集遗传算法》所得结果
总价值为3103, 总重量为1000。
我们算法所得结果: 总价值为3103, 总重量为1000。
我们所求得最优解的个体分配情况为:
11010 10111 10110 11011 01111 11101 00001 01001 10000
01000
算法 最大迭代次数 总价值为 总重量为
传统的算法 400 3077 999
佳点集算法 70 3103 1000
遗传算法 75 3103 1000
// knapsack.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <AfxWin.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <conio.h>
#include <stdio.h>
// 重要常量参数
#define popsize 200 //种群的规模
#define pc 0.618 //杂交概率
#define pm 0.03 //变异概率
#define lchrom 50 //染色体长度
#define maxgen 1000 //最大进化代数
struct population
{
unsigned int chrom[lchrom]; //染色体
double weight; //背包重量
double fitness; //适应度
unsigned int parent1,parent2,cross; //双亲、交叉点
};
//新生代种群、父代种群
struct population oldpop[popsize],newpop[popsize];
//背包问题中物体重量、收益、背包容量
int weight[lchrom],profit[lchrom],contain;
//种群的总适应度、最小、最大、平均适应度
double sumfitness,minfitness,maxfitness,avgfitness;
//计算适应度时使用的 惩罚函数系数
double alpha;
//一个种群中最大和最小适应度的个体
int minpop,maxpop;
/* 读入背包信息,并且计算惩罚函数系数 */
void read_infor()
{
FILE *fp;
int j;
//获取背包问题信息文件
if ((fp=fopen("knapsack.txt","r"))==NULL)
{
//读取文件失败
AfxMessageBox("The file is not found",MB_OK,NULL);
return;
}
//读入物体收益信息
for (j=0;j<lchrom;j++)
{
fscanf(fp,"%d",&profit[j]);
}
//读入物体重量信息
for (j=0;j<lchrom;j++)
{
fscanf(fp,"%d",&weight[j]);
}
//读入背包容量
fscanf(fp,"%d",&contain);
fclose(fp);
}
//根据计算的个体重量,判断此个体是否该留在群体中
double cal_weight(unsigned int *chr)
{
int j;
double pop_weight;//背包重量
pop_weight=0;
for (j=0;j<lchrom;j++)
{
pop_weight=pop_weight+(*chr)*weight[j];
chr++;
}
return pop_weight;
}
/* 种群中个体适应度计算*/
double cal_fit(unsigned int *chr)
{
int j;
double pop_profit;//适应度
pop_profit=0;
// pop_weight=0;
for (j=0;j<lchrom;j++)
{
pop_profit=pop_profit+(*chr)*profit[j];
// pop_weight=pop_weight+(*chr)*weight[j];
chr++;
}
return pop_profit;
}
/* 群体适应度的最大最小值以及其他信息 */
void statistics(struct population *pop)
{
int i;
double tmp_fit;
sumfitness=pop[0].fitness;
minfitness=pop[0].fitness;
minpop=0;
maxfitness=pop[0].fitness;
maxpop=0;
for (i=1;i<popsize;i++)
{
//计算种群的总适应度
sumfitness=sumfitness+pop[i].fitness;
tmp_fit=pop[i].fitness;
//选择种群中最大适应度的个体
if ((tmp_fit>maxfitness)&&((int)(tmp_fit*10)%10==0))
{
maxfitness=pop[i].fitness;
maxpop=i;
}
//选择种群中最小适应度的个体
if (tmp_fit<minfitness)
{
minfitness=pop[i].fitness;
minpop=i;
}
//计算平均适应度
avgfitness=sumfitness/(float)popsize;
}
// printf("\nthe max pop = %d;",maxpop);
// printf("\nthe min pop = %d;",minpop);
// printf("\nthe sumfitness = %f\n",sumfitness);
}
//报告种群信息
void report(struct population *pop,int gen)
{
int j;
int pop_weight=0;
printf("the generation is %d.\n",gen); //输出种群的代数
//输出种群中最大适应度个体的染色体信息
printf("The population's chrom is: \n");
for (j=0;j<lchrom;j++)
{
if (j%5==0)
{ printf(" ");}
printf("%1d",pop[maxpop].chrom[j]);
}
//输出群体中最大适应度
printf("\nThe population's max fitness is %d.",(int)pop[maxpop].fitness);
printf("\nThe knapsack weight is %d.\n\n",(int)pop[maxpop].weight);
}
/* 生成初始种群 */
void initpop()
{
int i,j,ispop;
double tmpWeight;
//变量用于判断是否为满足条件的个体
ispop=false;
//生成popsize个种群个体
for(i=0;i<popsize;i++)
{
while (!ispop)
{
for(j=0;j<lchrom;j++)
{
oldpop[i].chrom[j]=rand()%2; //随机生成个体的染色体
oldpop[i].parent1=0; //双亲
oldpop[i].parent2=0;
oldpop[i].cross=0; //交叉点
}
//选择重量小于背包容量的个体,即满足条件
tmpWeight=cal_weight(oldpop[i].chrom);
if (tmpWeight<=contain)
{
oldpop[i].fitness=cal_fit(oldpop[i].chrom);
oldpop[i].weight=tmpWeight;
oldpop[i].parent1=0;
oldpop[i].parent2=0;
oldpop[i].cross=0;
ispop=true;
}
}
//此个体可以加入到种群中
ispop=false;
}
}
/* 遗传操作 */
//概率选择试验
int execise(double probability)
{
double pp;
//如果生成随机数大于相应的概率则返回真,否则试验不成功
pp=(double)(rand()%20001/20000.0);
if (pp<=probability) return 1;
return 0;
}
// 选择进行交叉操作的个体
int selection(int pop)
{
double wheel_pos,rand_Number,partsum;
int parent;
//赌轮法选择
rand_Number=(rand()%2001)/2000.0;
wheel_pos=rand_Number*sumfitness; //赌轮大小
partsum=0;
parent=0;
do{
partsum=partsum+oldpop[parent].fitness;
parent=parent+1;
} while (partsum<wheel_pos && parent<popsize);
return parent-1;
}
/* 交叉操作 */
int crossover(unsigned int *parent1,unsigned int *parent2,int i)
{
int j,cross_pos;
if (execise(pc))
{
//生成交叉位置0,1,...(lchrom-2)
cross_pos=rand()%(lchrom-1);
}
else cross_pos=lchrom-1;
for (j=0;j<=cross_pos;j++)
{ //保留复制;
//包括在概率选择不成功时,父体完全保留
newpop[i].chrom[j]=parent1[j];
}
for(j=cross_pos+1;j<=(lchrom-1);j++)
{
//从交叉点开始交叉
newpop[i].chrom[j]=parent2[j];
}
//记录交叉位置
newpop[i].cross=cross_pos;
return 1;
}
/* 变异操作 */
int mutation(unsigned int alleles)
{
if (execise(pm))
{
if (alleles)
alleles=0;
else alleles=1;
}
//返回变异值,或者返回原值
return alleles;
}
/* 群体更新 */
void generation()
{
unsigned int i,j,mate1,mate2;
double tmpWeight;
int ispop;//记录是否是符合条件的个体
i=0;
while (i<popsize)
{
ispop=false;
while (!ispop)
{
//选择
mate1=selection(i);
mate2=selection(i+1);
//交叉
crossover(oldpop[mate1].chrom,oldpop[mate2].chrom,i);
//变异
for (j=0;j<lchrom;j++)
{
newpop[i].chrom[j]=mutation(newpop[i].chrom[j]);
}
//选择重量小于背包容量的个体,即满足条件
tmpWeight=cal_weight(newpop[i].chrom);
if (tmpWeight<=contain)
{
newpop[i].fitness=cal_fit(newpop[i].chrom);
newpop[i].weight=tmpWeight;
newpop[i].parent1=mate1;
newpop[i].parent2=mate2;
ispop=true;
}
}
//此个体可以加入到种群中
i=i+1;
}
}
void main(int argc, char* argv[])
{
int gen,oldmaxpop,k;
double oldmax;
read_infor();//读入背包信息
gen=0;
srand( (unsigned)time( NULL ) );//置随机种子
initpop();
memcpy(&newpop,&oldpop,popsize*sizeof(struct population));
statistics(newpop);//统计新生种群的信息
report(newpop,gen);
while(gen<maxgen)
{
gen=gen+1;
if (gen%100==0)
{
srand( (unsigned)time( NULL ) );//置随机种子
}
oldmax=maxfitness;
oldmaxpop=maxpop;
generation();
statistics(newpop); //统计新生代种群信息
//如果新生代种群中个体的最大适应度小于老一代种群
//个体的最大适应度,则保存老一代种群个体的最大适应度
//否则报告新生代的最大适应度
if (maxfitness<oldmax)
{
for(k=0;k<lchrom;k++)
newpop[minpop].chrom[k]=oldpop[oldmaxpop].chrom[k];
newpop[minpop].fitness=oldpop[oldmaxpop].fitness;
newpop[minpop].parent1=oldpop[oldmaxpop].parent1;
newpop[minpop].parent2=oldpop[oldmaxpop].parent2;
newpop[minpop].cross=oldpop[oldmaxpop].cross;
statistics(newpop);
}
else if (maxfitness>oldmax)
{
report(newpop,gen);
}
//保存新生代种群的信息到老一代种群信息空间
memcpy(&oldpop,&newpop,popsize*sizeof(struct population));
}
printf("It is over.");
getch();
}
2. r软件,rbga,可以做多个目标函数的遗传算法吗
遗传算法的操作使用适者生存的原则,在潜在的种群中逐次产生一个近似最优解的方案,在每一代中,根据个体在问题域中的适应度值和从自然遗传学中借鉴来的再造方法进行个体选择,产生一个新的近似解。这个过程会导致种群中个体的进化,得到的新个体比原来个体更能适应环境,就像自然界中的改造一样。
如果从生物进化的角度,我们可以这样理解。在一个种群中,个体数量已经有一定规模,为了进化发展,通过选择和繁殖产生下一代的个体,其中繁殖过程包括交配和突变。根据适者生存的原则,选择过程会根据新个体的适应度进行保留或淘汰,但也不是完全以适应度高低作为导向,如果单纯选择适应度高的个体可能会产生局部最优的种群,而非全局最优,这个种群将不会再进化,称为早熟。之后,通过繁殖过程,让个体两两交配产生下一代新个体,上一代个体中优秀的基因会保留给下一代,而劣制的基因将被个体另一半的基因所代替。最后,通过小概率事件发生基因突变,通过突变产生新的下一代个体,实现种群的变异进化。
经过这一系列的选择、交配和突变的过程,产生的新一代个体将不同于初始的一代,并一代一代向增加整体适应度的方向发展,因为最好的个体总是更多的被选择去产生下一代,而适应度低的个体逐渐被淘汰掉。这样的过程不断的重复:每个个体被评价,计算出适应度,两个个体交配,然后突变,产生第三代。周而复始,直到终止条件满足为止。
3. matlab遗传算法求最小包容圆
首先定义优化目标函数:
functionr=rmax(p,x)
%p:已知平面点集。p的每一列就是一点的xy坐标。
%x:包络圆的中心坐标。
a=x(1);b=x(2);
r=max(((p(1,:)-a).^2+(p(2,:)-b).^2).^0.5);
易知,当r取值最小时,即为最小包络圆。
下面是matlab求解程序:
p=rand(2,10);%已知平面点列。p的每一列就是一点的xy坐标。
lb=min(p')';%
ub=max(p')';%限定包络圆的中心范围。
options=gaoptimset('TimeLimit',150);%设定求解时间
[xfvalexit]=ga(@(x)rmax(p,x),2,[],[],[],[],lb,ub,[],options);%x就是包络圆中心的横纵坐标。
运行图:
4. matlab用遗传算法解决TSP的问题,求帮助
把下面的(1)-(7)依次存成相应的.m文件,在(7)的m文件下运行就可以了
(1) 适应度函数fit.m
function fitness=fit(len,m,maxlen,minlen)
fitness=len;
for i=1:length(len)
fitness(i,1)=(1-(len(i,1)-minlen)/(maxlen-minlen+0.0001)).^m;
end
(2)个体距离计算函数 mylength.m
function len=myLength(D,p)
[N,NN]=size(D);
len=D(p(1,N),p(1,1));
for i=1:(N-1)
len=len+D(p(1,i),p(1,i+1));
end
end
(3)交叉操作函数 cross.m
function [A,B]=cross(A,B)
L=length(A);
if L<10
W=L;
elseif ((L/10)-floor(L/10))>=rand&&L>10
W=ceil(L/10)+8;
else
W=floor(L/10)+8;
end
p=unidrnd(L-W+1);
fprintf('p=%d ',p);
for i=1:W
x=find(A==B(1,p+i-1));
y=find(B==A(1,p+i-1));
[A(1,p+i-1),B(1,p+i-1)]=exchange(A(1,p+i-1),B(1,p+i-1));
[A(1,x),B(1,y)]=exchange(A(1,x),B(1,y));
end
end
(4)对调函数 exchange.m
function [x,y]=exchange(x,y)
temp=x;
x=y;
y=temp;
end
(5)变异函数 Mutation.m
function a=Mutation(A)
index1=0;index2=0;
nnper=randperm(size(A,2));
index1=nnper(1);
index2=nnper(2);
%fprintf('index1=%d ',index1);
%fprintf('index2=%d ',index2);
temp=0;
temp=A(index1);
A(index1)=A(index2);
A(index2)=temp;
a=A;
end
(6)连点画图函数 plot_route.m
function plot_route(a,R)
scatter(a(:,1),a(:,2),'rx');
hold on;
plot([a(R(1),1),a(R(length(R)),1)],[a(R(1),2),a(R(length(R)),2)]);
hold on;
for i=2:length(R)
x0=a(R(i-1),1);
y0=a(R(i-1),2);
x1=a(R(i),1);
y1=a(R(i),2);
xx=[x0,x1];
yy=[y0,y1];
plot(xx,yy);
hold on;
end
end
(7)主函数
clear;
clc;
%%%%%%%%%%%%%%%输入参数%%%%%%%%
N=50; %%城市的个数
M=100; %%种群的个数
C=100; %%迭代次数
C_old=C;
m=2; %%适应值归一化淘汰加速指数
Pc=0.4; %%交叉概率
Pmutation=0.2; %%变异概率
%%生成城市的坐标
pos=randn(N,2);
%%生成城市之间距离矩阵
D=zeros(N,N);
for i=1:N
for j=i+1:N
dis=(pos(i,1)-pos(j,1)).^2+(pos(i,2)-pos(j,2)).^2;
D(i,j)=dis^(0.5);
D(j,i)=D(i,j);
end
end
%%如果城市之间的距离矩阵已知,可以在下面赋值给D,否则就随机生成
%%生成初始群体
popm=zeros(M,N);
for i=1:M
popm(i,:)=randperm(N);
end
%%随机选择一个种群
R=popm(1,:);
figure(1);
scatter(pos(:,1),pos(:,2),'rx');
axis([-3 3 -3 3]);
figure(2);
plot_route(pos,R); %%画出种群各城市之间的连线
axis([-3 3 -3 3]);
%%初始化种群及其适应函数
fitness=zeros(M,1);
len=zeros(M,1);
for i=1:M
len(i,1)=myLength(D,popm(i,:));
end
maxlen=max(len);
minlen=min(len);
fitness=fit(len,m,maxlen,minlen);
rr=find(len==minlen);
R=popm(rr(1,1),:);
for i=1:N
fprintf('%d ',R(i));
end
fprintf('\n');
fitness=fitness/sum(fitness);
distance_min=zeros(C+1,1); %%各次迭代的最小的种群的距离
while C>=0
fprintf('迭代第%d次\n',C);
%%选择操作
nn=0;
for i=1:size(popm,1)
len_1(i,1)=myLength(D,popm(i,:));
jc=rand*0.3;
for j=1:size(popm,1)
if fitness(j,1)>=jc
nn=nn+1;
popm_sel(nn,:)=popm(j,:);
break;
end
end
end
%%每次选择都保存最优的种群
popm_sel=popm_sel(1:nn,:);
[len_m len_index]=min(len_1);
popm_sel=[popm_sel;popm(len_index,:)];
%%交叉操作
nnper=randperm(nn);
A=popm_sel(nnper(1),:);
B=popm_sel(nnper(2),:);
for i=1:nn*Pc
[A,B]=cross(A,B);
popm_sel(nnper(1),:)=A;
popm_sel(nnper(2),:)=B;
end
%%变异操作
for i=1:nn
pick=rand;
while pick==0
pick=rand;
end
if pick<=Pmutation
popm_sel(i,:)=Mutation(popm_sel(i,:));
end
end
%%求适应度函数
NN=size(popm_sel,1);
len=zeros(NN,1);
for i=1:NN
len(i,1)=myLength(D,popm_sel(i,:));
end
maxlen=max(len);
minlen=min(len);
distance_min(C+1,1)=minlen;
fitness=fit(len,m,maxlen,minlen);
rr=find(len==minlen);
fprintf('minlen=%d\n',minlen);
R=popm_sel(rr(1,1),:);
for i=1:N
fprintf('%d ',R(i));
end
fprintf('\n');
popm=[];
popm=popm_sel;
C=C-1;
%pause(1);
end
figure(3)
plot_route(pos,R);
axis([-3 3 -3 3]);