function [bestCVaccuarcy,bestc,bestg,ga_option] = gaSVMcgForClass(train_label,train,ga_option)
% gaSVMcgForClass
% by faruto
% 2009.10.07
%% 参数初始化
if nargin == 2
ga_option = struct('maxgen',100,'sizepop',20,'pCrossover',0.4,'pMutation',0.01, ...
'cbound',[0.1,100],'gbound',[0.01,1000],'v',3);
end
% maxgen:最大的进化代数,默认为100,一般取值范围为[100,500]
% sizepop:种群最大数量,默认为20,一般取值范围为[20,100]
% pCrossover:交叉概率,默认为0.4,一般取值范围为[0.4,0.99]
% pMutation:变异概率,默认为0.01,一般取值范围为[0.0001,0.1]
% cbound = [cmin,cmax],参数c的变化范围,默认为[0.1,100]
% gbound = [gmin,gmax],参数g的变化范围,默认为[0.01,1000]
% v:SVM Cross Validation参数,默认为3
c_len_chromosome = ceil(log2((ga_option.cbound(2)-ga_option.cbound(1))*100));
g_len_chromosome = ceil(log2((ga_option.gbound(2)-ga_option.gbound(1))*100));
len_chromosome = c_len_chromosome+g_len_chromosome;
% 将种群信息定义为一个结构体
individuals=struct('fitness',zeros(1,ga_option.sizepop), ...
'chromosome',zeros(ga_option.sizepop,len_chromosome));
% 每一代种群的平均适应度
avgfitness_gen = zeros(1,ga_option.maxgen);
% 每一代种群的最佳适应度
bestfitness_gen = zeros(1,ga_option.maxgen);
% 最佳适应度
bestfitness = 0;
% 适应度最好的染色体
bestchromosome = zeros(1,len_chromosome);
%% 初始化种群
for i = 1:ga_option.sizepop
% 编码
individuals.chromosome(i,:) = unidrnd(2,1,len_chromosome)-1;
% 解码
[c,g] = ga_decode(individuals.chromosome(i,:),ga_option.cbound,ga_option.gbound);
% 计算初始适应度(CV准确率)
cmd = ['-v ',num2str(ga_option.v),' -c ',num2str( c ),' -g ',num2str( g )];
individuals.fitness(i) = svmtrain(train_label, train, cmd);
end
% 找最佳的适应度和最好的染色体的位置
[bestfitness,bestindex]=max(individuals.fitness);
% 最好的染色体
bestchromosome = individuals.chromosome(bestindex,:);
% 初始染色体的平均适应度
avgfitness_gen(1) = sum(individuals.fitness)/ga_option.sizepop;
%% 迭代寻优
for i=1:ga_option.maxgen
% Selection Operator
individuals = Selection(individuals,ga_option);
% Crossover Operator
individuals = Crossover(individuals,ga_option);
% Mutation Operator
individuals = Mutation(individuals,ga_option);
% 计算适应度
for j = 1:ga_option.sizepop
% 解码
[c,g] = ga_decode(individuals.chromosome(j,:),ga_option.cbound,ga_option.gbound);
% 计算初始适应度(CV准确率)
cmd = ['-v ',num2str(ga_option.v),' -c ',num2str( c ),' -g ',num2str( g )];
individuals.fitness(j) = svmtrain(train_label, train, cmd);
end
% 找最佳的适应度和最好的染色体的位置
[new_bestfitness,bestindex]=max(individuals.fitness);
% 最好的染色体
new_bestchromosome = individuals.chromosome(bestindex,:);
[new_c,g] = ga_decode(new_bestchromosome,ga_option.cbound,ga_option.gbound);
[c,g] = ga_decode(bestchromosome,ga_option.cbound,ga_option.gbound);
if new_bestfitness == bestfitness && new_c < c
bestfitness = new_bestfitness;
bestchromosome = new_bestchromosome;
end
if new_bestfitness > bestfitness
bestfitness = new_bestfitness;
bestchromosome = new_bestchromosome;
end
% 这一代染色体的最佳适应度
bestfitness_gen(i) = bestfitness;
% 这一代染色体的平均适应度
avgfitness_gen(i) = sum(individuals.fitness)/ga_option.sizepop;
end
%% 结果分析
figure;
hold on;
plot(bestfitness_gen,'r');
plot(avgfitness_gen);
legend('最佳适应度','平均适应度');
title(['适应度曲线','(终止代数=',num2str(ga_option.maxgen),',种群数量pop=',num2str(ga_option.sizepop),')']);
xlabel('进化代数');ylabel('适应度');
axis([0 ga_option.maxgen 0 100]);
grid on;
[bestc,bestg] = ga_decode(bestchromosome,ga_option.cbound,ga_option.gbound);
bestCVaccuarcy = bestfitness_gen(ga_option.maxgen);