📄 gajava.txt
字号:
}
/**
* 将某个染色体解析为内容友好的字符串
*/
private String parseToString(int chrom) {
StringBuilder result = new StringBuilder();
StringBuilder sum = new StringBuilder();
StringBuilder prod = new StringBuilder();
for(int i=0; i<chrom_length; i++) {
if(population[chrom][i] == 0)
sum.append((i+1) + "+");
else
prod.append((i+1) + "*");
}
sum.replace(sum.length()-1, sum.length(), "="+sum_tagart);
prod.replace(prod.length()-1, prod.length(), "="+product_targart);
result.append("找到了合适的纸牌组合,分别是:" + System.getProperty("line.separator"));
result.append(sum.toString() + System.getProperty("line.separator"));
result.append(prod.toString() + System.getProperty("line.separator"));
return result.toString();
}
/**
* 判断某个染色体是否就是最终答案
*/
private boolean isAnswer(int chrom) {
if(getFitness(chrom) == 0f) {
return true;
}
return false;
}
/**
* 对染色体进行变异
*/
private void mutation(int chrom) {
for(int i=0; i<chrom_length; i++) {
if(rand.nextFloat()<mutation_rate) {
population[chrom][i] = (population[chrom][i]+1)%2;
}
}
}
/**
* 将两个染色体进行杂交,winner不变,只修改loser
*/
private void crossover(int winner, int loser) {
for(int i=0; i<chrom_length; i++) {
if(rand.nextFloat()<crossover_rate)
population[loser][i] = population[winner][i];
}
}
/**
* 取得第i个染色体的符合度,符合度越小越好
*/
private float getFitness(int chrom) {
int sum = 0;
int prod = 1;
for(int i=0; i<chrom_length; i++) {
if(population[chrom][i]==0)
sum += (1+i);
else
prod *= (1+i);
}
return (float)Math.abs(sum - sum_tagart)/sum_tagart + (float)Math.abs(prod - product_targart)/product_targart;
}
/**
* 初始化人口池,数组的内容为0或者1,
* 0标识该扑克牌被分配到求和组
* 1标识该扑克牌被分配到求积组
*/
private void initPopuation(int[][] population2) {
for(int i=0; i<pop_size; i++)
for(int j=0; j<chrom_length; j++) {
if(rand.nextFloat()<0.5f)
population[i][j] = 0;
else
population[i][j] = 1;
}
}
}
计算智能课的遗传算法上完了,老师布置了一个简单的应用,用java实现了下。
首先是题目要求:
A given function is as follows: Use genetic algorithm to find a near-maximal value in
f==xsin(10*pi*x)+2
[-1,2]. In addition, the required precision is six places after the decimal point.
代码实现如下:
import java.util.Random;
public class GA {
public static final double A=-1;//下界
public static final double B=2;//
public static final int POP_SIZE=30;//种群数目
public static final int M=22; //编码位数
public static String[]pop=new String[POP_SIZE];//种群编码
public static double[]result=new double[POP_SIZE];//种群代表的结果
public static final int LENGTH=22;//编码长度,因为要精确到小数点后六位,所以编为22位长,有一公式可参考
public static final int MJ2=4194304;//2^22
public static double[]fitness=new double[POP_SIZE];//存放种群适应度
public static final double PC=0.95;//交叉率
public static final double PM=0.05;//变异率
public static double[]p=new double[POP_SIZE];//轮盘赌方法个体适应度概率
public static double[]q=new double[POP_SIZE];//q[i]是前n项p之和
public static Random random=new Random();//用于产生随机数的工具
public static Best best=new Best();//记录最佳答案的对象
/*
* 构造函数,初始化种群
*/
public GA(double d[])
{
for (int i = 0; i < d.length; i++) {
result[i]=d[i];
}
}
/*
* 编码方法,将解值表示为二进制字节码形式
*/
public void encoding()
{
for (int i = 0; i < result.length; i++) {
double d1=((result[i]-A)/(B-A))*(MJ2-1);
pop[i]=Integer.toBinaryString((int)d1);
}
for (int i = 0; i < pop.length; i++) {
if (pop[i].length()<LENGTH) {
int k=LENGTH-pop[i].length();
for (int j = 0; j <k ; j++) {
pop[i]="0"+pop[i];
}
}
}
for (int i = 0; i < pop.length; i++) {
//System.out.println(pop[i]+" "+pop[i].length());
}
}
/*
* 解码方法,讲二进制字节码还原为解
*/
public void decoding()
{
for (int i = 0; i < pop.length; i++) {
int k=Integer.parseInt(pop[i], 2);
result[i]=A+k*(B-A)/(MJ2-1);
}
for (int i = 0; i < result.length; i++) {
// System.out.println(result[i]);
}
}
/*
* 适应度函数
*/
public void fitness()
{
for (int i = 0; i < result.length; i++) {
fitness[i]=result[i]*(Math.sin(10*Math.PI*result[i]))+2;
//System.out.println(fitness[i]);
}
}
/*
* 交叉操作
*/
public void crossover()
{
for (int i = 0; i < POP_SIZE/2; i++) {
double d=random.nextDouble();
if(d<PC)
{
int k1=random.nextInt(POP_SIZE);
int k2=random.nextInt(POP_SIZE);
do {
k1=(int)random.nextInt(POP_SIZE);
k2=(int)random.nextInt(POP_SIZE);
} while (k1==k2);
int position=random.nextInt(LENGTH);
//System.out.println("crossover position="+position+" "+k1+ " "+k2);
String s11=null,s12=null,s21=null,s22=null;
//System.out.println(pop[k1]+" "+pop[k1].length());
s11=pop[k1].substring(0, position);
s12=pop[k1].substring(position,LENGTH);
//System.out.println(pop[k2]+" "+pop[k2].length());
s21=pop[k2].substring(0, position);
s22=pop[k2].substring(position,LENGTH);
pop[k1]=s11+s22;
pop[k2]=s21+s12;
}
}
}
/*
* 变异操作
*/
public void mutation()
{
for (int i = 0; i < pop.length; i++) {
for (int j = 0; j < LENGTH; j++) {
double k=random.nextDouble();
if(PM>k)
{
mutation(i,j);
}
}
}
}
public void mutation(int i,int j)
{
String s=pop[i];
StringBuffer sb=new StringBuffer(s);
if(sb.charAt(j)=='0')
sb.setCharAt(j, '1');
else
sb.setCharAt(j, '0');
pop[i]=sb.toString();
}
/*
* 轮盘赌方法
*/
public void roulettewheel()
{
decoding();
fitness();
double sum=0;
for (int i = 0; i <POP_SIZE; i++) {
sum=fitness[i]+sum;
}
for (int i = 0; i < POP_SIZE; i++) {
p[i]=fitness[i]/sum;
}
for (int i = 0; i < POP_SIZE; i++) {
for (int j = 0; j < i+1; j++) {
q[i]=p[j];
}
}
double []ran=new double[POP_SIZE];
String[] tempPop=new String[POP_SIZE];
for (int i = 0; i < ran.length; i++) {
ran[i]=random.nextDouble();
}
for (int i = 0; i < ran.length; i++) {
int k = 0;
for (int j = 0; j < q.length; j++) {
if(ran[i]<q[j])
{
k=j;
break;
}
else continue;
}
tempPop[i]=pop[k];
}
for (int i = 0; i < tempPop.length; i++) {
pop[i]=tempPop[i];
}
}
/*
* 一次进化
*/
public void evolution()
{
encoding();
crossover();
mutation();
decoding();
fitness();
roulettewheel();
findResult();
}
/*
*整个进化过程,n 表示进化多少代
*/
public void dispose(int n)
{
for (int i = 0; i < n; i++) {
evolution();
}
}
/*
* 取得结果
*/
public double findResult()
{
if(best==null)
best=new Best();
double max=best.fitness;
for (int i = 0; i < fitness.length; i++) {
if(fitness[i]>max)
{
best.fitness=fitness[i];
best.x=result[i];
best.str=pop[i];
//System.out.println(best.fitness);
}
}
return max;
}
/*
* 取得x值
*
*/
public double findx()
{
fitness();
double max=0;
int index=0;
for (int i = 0; i < fitness.length; i++) {
System.out.println(result[i]);
if(fitness[i]>max)
{
max=fitness[i];
index=i;
}
}
return result[index];
}
public static void main(String[] args) {
//d为初试种群
double d[]={-0.953181,-0.851234,-0.749723,-0.645386,-0.551234,-0.451644,-0.351534,-0.239566,-0.151234,0.145445,
0.245445,0.285174,0.345445,0.445445,0.542445,0.645445,0.786445,0.845445,0.923238,1.245445,
1.383453,1.454245,1.584566,1.644345,1.741545,1.845445,1.981254,-0.012853,0.083413,1.801231};
//初始化其它参数
GA ga=new GA(d);
System.out.println("种群进化中....");
//进化,这里进化10000次
ga.dispose(10000);
System.out.println("+++++++++++++++++++++++++++结果为:");
System.out.println("x="+best.x);
System.out.println("f="+best.fitness);
}
}
class Best { // 存储最佳的
public int generations;
public String str;
public double fitness;
public double x;
使用遗传算法求解函数 xyz*sin(xyz)的最大值
Posted on 2007-04-26 21:41 Zou Ang 阅读(2378) 评论(9) 编辑 收藏 所属分类:
最近学习遗传算法,写了这么一个小程序来计算函数 f(x,y,z) = xyz*sin(xyz)的最大值,这段程序经过小小改变就可以适应其他的函数最大值求解问题
首先介绍一下遗传算法,遗传算法就是模拟自然界中物竞天择,适者生存的法则,通过对解空间进行进化从而求得最优方案的方法,遗传算法的好处在于,即使算法中的某些参数不起作用了,整个算法还是可以正常地工作,也就是说,整体种群的走向是越来越好的
遗传算法的关键内容包括:
1. 染色体
首先对优化问题的解进行编码,编码后的一个解被称为一个染色体,组成染色体的元素称为基因。比如对于上面那个函数,我们就可以用24位的2进制串进行编码,首先8位2进制数代表x,中间为y,最后为z,x,y,z都属于[0,255]
2. 交配
将两个染色体进行交叉的操作被称为交配,交配可能提高染色体的适应值,也可能降低其适应值。通常交配是以一定的概率发生的。在程序中,我们通过随机交换两个染色体的一些位来体现。
3. 适应函数
我们需要使用一个函数来表现解的优异程度,这个函数只要可以反映出解的优劣即可,没必要很精确。适应函数就类似我们生存的环境,环境评估我们的生存能力,评估值高的更容易存活。
4. 变异
有时候种群中的某些个体会发生变异的现象,变异一般是以很小的概率发生的,但是变异增加了种群进化的不确定性,也让种群中的个体类型更加丰富。在程序中,我们用随机变化某一位来体现。
算法的流程为:
1.初始化种群
2.进行第一轮评估
3.交配
4.变异
5.评估
6.重新选择种群
7.若未达到结束条件,转3
随机数生成器:
package edu.zsu.zouang.util;
import java.util.Random;
public class Randomizer {
private int lower;
private int upper;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -