|
package com.gene; |
|
import java.text.DecimalFormat; |
|
import java.util.ArrayList; |
|
import java.util.Collections; |
|
import java.util.Comparator; |
|
import java.util.Random; |
|
|
|
|
|
public class Gene |
|
{ |
|
private static int groundCount; //The sum of individual genes |
|
private static int copulationCount; //sum of copulation is grundCount double |
|
private static int period; // sum of generation |
|
private static double copulationRate; //is Probability can copulation |
|
private static double mutationRate;//is Probability can mutation |
|
private static double max_x1; |
|
private static double min_x1; |
|
private static int randParameter1_x1; |
|
private static int randParameter2_x1; |
|
|
|
private static double max_x2; |
|
private static double min_x2; |
|
private static int randParameter1_x2; |
|
private static int randParameter2_x2; |
|
|
|
private final static DecimalFormat df = new DecimalFormat("##.#"); |
|
private static Random rand=new Random(); |
|
|
|
|
|
Gene(int groundCount,int period,double copulationRate,double mutationRate |
|
,double max_x1,double min_x1,int randParameter1_x1,int randParameter2_x1 |
|
,double max_x2,double min_x2,int randParameter1_x2,int randParameter2_x2) |
|
|
|
{ |
|
this.groundCount=groundCount; |
|
copulationCount=groundCount*2; |
|
this.period=period; |
|
this.copulationRate=copulationRate; |
|
this.mutationRate=mutationRate; |
|
this.max_x1=max_x1; |
|
this.min_x1=min_x1; |
|
this.randParameter1_x1=randParameter1_x1; |
|
this.randParameter2_x1=randParameter2_x1; |
|
this.max_x2=max_x2; |
|
this.min_x2=min_x2; |
|
this.randParameter1_x2=randParameter1_x2; |
|
this.randParameter2_x2=randParameter2_x2; |
|
|
|
} |
|
/* |
|
由於主函式被宣告為static,而 |
|
static method內的程式碼只能呼叫static method,因此 |
|
為了要讓主函式main呼叫,故必須宣告為static |
|
method。 |
|
*/ |
|
public ArrayList<Parameter> createListParameter() |
|
{ |
|
ArrayList<Parameter> listParameter=new ArrayList<Parameter>(); |
|
Parameter parameter; |
|
//查看亂數數值有沒有符合範圍,有的話add |
|
for(int i=0;i<groundCount;i++) |
|
{ |
|
parameter=new Parameter(); |
|
double number=100; //先設定這樣 |
|
while (number>max_x1|| number<min_x1) |
|
{ |
|
int integer=rand.nextInt(randParameter1_x1)+randParameter2_x1; |
|
double doub=rand.nextDouble(); |
|
number=Double.parseDouble(df.format(integer+doub)); |
|
} |
|
parameter.setNumberX1(number); |
|
number=100; |
|
while (number>max_x2|| number<min_x2) |
|
{ |
|
int integer=rand.nextInt(randParameter1_x2)+randParameter2_x2; |
|
double doub=rand.nextDouble(); |
|
number=Double.parseDouble(df.format(integer+doub)); |
|
} |
|
parameter.setNumberX2(number); |
|
|
|
// 十進位轉二進位 |
|
parameter.setBinaryX1(getBinary(parameter.getNumberX1()));; |
|
parameter.setBinaryX2(getBinary(parameter.getNumberX2()));; |
|
parameter=equation(parameter); |
|
listParameter.add(parameter); |
|
} |
|
listParameter=sortListParameter(listParameter); |
|
return listParameter; |
|
} |
|
|
|
//輪盤式選擇(roulette wheel selection) |
|
public ArrayList<Parameter> reproduction(ArrayList<Parameter> ListParameter) |
|
{ |
|
ArrayList<Parameter> ListParameterReproduction=new ArrayList<Parameter>() ; |
|
|
|
ArrayList<Parameter> ListParameterTop10Percents=new ArrayList<Parameter>(ListParameter.subList(0, (int)(groundCount*0.1))); |
|
ArrayList<Parameter> ListParameterTop30Percents=new ArrayList<Parameter>(ListParameter.subList(0, (int)(groundCount*0.3))); |
|
ArrayList<Parameter> ListParameterTop70Percents=new ArrayList<Parameter>(ListParameter.subList(0, (int)(groundCount*0.7))); |
|
ArrayList<Parameter> ListParameterTop90Percents=new ArrayList<Parameter>(ListParameter.subList(0, (int)(groundCount*0.9))); |
|
ListParameterReproduction.addAll(ListParameterTop10Percents); |
|
ListParameterReproduction.addAll(ListParameterTop30Percents); |
|
ListParameterReproduction.addAll(ListParameterTop70Percents); |
|
ListParameterReproduction.addAll(ListParameterTop90Percents); |
|
|
|
// ArrayList<Parameter> ListParameterCreate=new ArrayList<Parameter>(createListParameter().subList(0, (int)(groundCount*0.3))); |
|
// ListParameterReproduction.addAll(ListParameterCreate); |
|
ListParameterReproduction=sortListParameter(ListParameterReproduction); |
|
return ListParameterReproduction; |
|
} |
|
|
|
/* |
|
* 設定交配機率,兩個基因的x1前四碼做交換,和x2的後四碼做交換,但如果交換後數值超過限定值的話,就不交配,隨機其中一組 |
|
*/ |
|
public ArrayList<Parameter> copulation(ArrayList<Parameter> ListParameter) |
|
{ |
|
|
|
//隨機挑兩個數值 |
|
int option1,option2; |
|
String option1_Binaryx1, option1_Binaryx2; |
|
String option2_Binaryx1, option2_Binaryx2; |
|
|
|
String subBinary; |
|
boolean isRunning=true; |
|
ArrayList<Parameter> ListParameterCopulation=new ArrayList<Parameter>(); |
|
Parameter parameter=new Parameter(); |
|
|
|
for(int i=0;i<copulationCount;i++) |
|
{ |
|
parameter=new Parameter(); |
|
while(isRunning==true) |
|
{ |
|
int Probability=rand.nextInt(10); |
|
//突變 |
|
if(Probability<1) |
|
{ |
|
int mutationOption=rand.nextInt(ListParameter.size()); |
|
parameter=mutation(ListParameter.get(mutationOption)); |
|
} |
|
else |
|
{ |
|
option1=rand.nextInt(ListParameter.size()); |
|
option2=rand.nextInt(ListParameter.size()); |
|
|
|
option1_Binaryx1=ListParameter.get(option1).getBinaryX1(); |
|
option1_Binaryx2=ListParameter.get(option1).getBinaryX2(); |
|
|
|
option2_Binaryx1=ListParameter.get(option2).getBinaryX1(); |
|
option2_Binaryx2=ListParameter.get(option2).getBinaryX2(); |
|
|
|
subBinary=option1_Binaryx1.substring(0, 4)+option2_Binaryx1.substring(4, 8); |
|
parameter.setBinaryX1(subBinary); |
|
subBinary=option2_Binaryx2.substring(0, 4)+option1_Binaryx2.substring(4, 8); |
|
parameter.setBinaryX2(subBinary); |
|
|
|
parameter=getDecimal(parameter); |
|
} |
|
if (checkRange(parameter)==true) |
|
isRunning=false; |
|
} |
|
isRunning=true; |
|
|
|
parameter=equation(parameter); |
|
ListParameterCopulation.add(parameter); |
|
|
|
parameter=null; |
|
|
|
} |
|
ListParameterCopulation.addAll(ListParameter); |
|
ListParameterCopulation=sortListParameter(ListParameterCopulation); |
|
return ListParameterCopulation; |
|
} |
|
|
|
public Parameter mutation(Parameter parameter) |
|
{ |
|
int mutationPart=rand.nextInt(2); |
|
String binary; |
|
boolean isRunning=true; |
|
|
|
while(isRunning==true) |
|
{ |
|
mutationPart=rand.nextInt(8); |
|
binary=parameter.getBinaryX1(); |
|
|
|
if(mutationPart==0) |
|
{ |
|
mutationPart=rand.nextInt(8); |
|
binary=parameter.getBinaryX1(); |
|
if(binary.charAt(mutationPart)=='1') |
|
{ |
|
if(mutationPart==0) |
|
binary='0'+binary.substring(1); |
|
else if(mutationPart==7) |
|
binary=binary.substring(0, 7)+'0'; |
|
else |
|
binary=binary.substring(0, mutationPart)+'0'+binary.substring(mutationPart+1); |
|
System.out.println("原本:"+parameter.getBinaryX1()+"部分"+mutationPart+"後來:"+binary); |
|
} |
|
else |
|
{ |
|
if(mutationPart==0) |
|
binary='1'+binary.substring(1); |
|
else if(mutationPart==7) |
|
binary=binary.substring(0, 7)+'1'; |
|
else |
|
binary=binary.substring(0, mutationPart)+'1'+binary.substring(mutationPart+1); |
|
System.out.println("原本:"+parameter.getBinaryX1()+"部分"+mutationPart+"後來:"+binary); |
|
} |
|
parameter.setBinaryX1(binary); |
|
parameter=getDecimal(parameter); |
|
parameter=equation(parameter); |
|
if(checkRange(parameter)==true) |
|
{ |
|
isRunning=false; |
|
return parameter; |
|
} |
|
} |
|
else |
|
{ |
|
mutationPart=rand.nextInt(8); |
|
binary=parameter.getBinaryX2(); |
|
if(binary.charAt(mutationPart)=='1') |
|
{ |
|
if(mutationPart==0) |
|
binary='0'+binary.substring(1); |
|
else if(mutationPart==7) |
|
binary=binary.substring(0, 7)+'0'; |
|
else |
|
binary=binary.substring(0, mutationPart)+'0'+binary.substring(mutationPart+1); |
|
System.out.println("原本:"+parameter.getBinaryX1()+"部分"+mutationPart+"後來:"+binary); |
|
} |
|
else |
|
{ |
|
if(mutationPart==0) |
|
binary='1'+binary.substring(1); |
|
else if(mutationPart==7) |
|
binary=binary.substring(0, 7)+'1'; |
|
else |
|
binary=binary.substring(0, mutationPart)+'1'+binary.substring(mutationPart+1); |
|
System.out.println("原本:"+parameter.getBinaryX1()+"部分"+mutationPart+"後來:"+binary); |
|
} |
|
parameter.setBinaryX1(binary); |
|
parameter=getDecimal(parameter); |
|
parameter=equation(parameter); |
|
if(checkRange(parameter)==true) |
|
{ |
|
isRunning=false; |
|
return parameter; |
|
} |
|
} |
|
} |
|
return parameter; |
|
} |
|
|
|
public void showListParameter(ArrayList<Parameter> list ,String action) |
|
{ |
|
System.out.println(action); |
|
for(int i=0;i<list.size();i++) |
|
System.out.println("第"+(i+1)+"組:x1:"+list.get(i).getNumberX1()+",xb1:"+list.get(i).getBinaryX1()+",x2:"+list.get(i).getNumberX2()+",xb2:"+list.get(i).getBinaryX2()+",f:"+list.get(i).getF()); |
|
} |
|
|
|
public ArrayList<Parameter> sortListParameter(ArrayList<Parameter> list) |
|
{ |
|
//sort array |
|
Collections.sort(list,new Comparator<Parameter>() |
|
{ |
|
@Override |
|
public int compare(Parameter o1, Parameter o2) |
|
{ |
|
// TODO Auto-generated method stub |
|
if(Double.compare(o1.getF(), o2.getF())==-1) |
|
return 1;//o1>o2 ,higher then the front |
|
else if(Double.compare(o1.getF(), o2.getF())==0) |
|
return 0; |
|
else |
|
return -1; |
|
} |
|
}); |
|
return list; |
|
} |
|
|
|
public Parameter getDecimal(Parameter parameter) |
|
{ |
|
String binaryX1=parameter.getBinaryX1(); |
|
String binaryX2=parameter.getBinaryX2(); |
|
DecimalFormat df = new DecimalFormat("##.#"); |
|
double numberX1=(double)(Integer.valueOf(binaryX1,2))/10-3; |
|
double numberX2=(double)(Integer.valueOf(binaryX2,2))/10-3; |
|
|
|
numberX1=Double.parseDouble(df.format(numberX1)); |
|
numberX2=Double.parseDouble(df.format(numberX2)); |
|
parameter.setNumberX1(numberX1); |
|
parameter.setNumberX2(numberX2); |
|
|
|
return parameter; |
|
} |
|
|
|
public String getBinary(double number) |
|
{ |
|
int binary; |
|
binary=(int)((number+3)*10); |
|
//二進位補零算式 |
|
String binaryString=Integer.toBinaryString(0x100 | binary).substring(1); |
|
return binaryString; |
|
} |
|
|
|
public boolean checkRange(Parameter parameter) |
|
{ |
|
double numberX1=parameter.getNumberX1(); |
|
double numberX2=parameter.getNumberX2(); |
|
|
|
if(min_x1<=numberX1 && numberX1<=max_x1 && min_x2<=numberX2 && numberX2<=max_x2) |
|
return true; |
|
else |
|
return false; |
|
} |
|
|
|
public Parameter equation( Parameter parameter) |
|
{ |
|
double f=21.5+parameter.numberX1*Math.sin(4.0*Math.PI*parameter.numberX1)+parameter.numberX2*Math.sin(20.0*Math.PI*parameter.numberX2); |
|
f=Double.parseDouble(df.format(f)); |
|
parameter.setF(f); |
|
return parameter; |
|
} |
|
} |