?? 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 + -