package myMOEA;
import java.util.Random;
public class MOEA implements ComputeOperation,
MutateOperation,
RankOperation{
Random ri = new Random(System.currentTimeMillis());
//************************* Dominance ***************************************
public int Dominance(double[] x1, double[] x2){
int result = 0;
if((x1[0] < x2[0])&&(x1[1] <= x2[1])){ // x1 dominates x2
result = 1;
}
else if((x1[0] <= x2[0])&&(x1[1] < x2[1])){
result = 1;
}
else if((x1[0] > x2[0])&&(x1[1] >= x2[1])){ //x2 dominates x1
result = -1;
}
else if((x1[0] >= x2[0])&&(x1[1] > x2[1])){
result = -1;
}//it's possible that no one of these two is dominating
return result;
}
//************************* Compute ******************************************
public void Compute(double x, double[] y){
y[0] = Math.cos(x) * (1 - x * x);
y[1] = Math.sin(x) * (1 - x * x);
}
//************************* Mutate ******************************************
public double Mutate(double x){
x += Math.PI * ri.nextGaussian();
if(x < 0){
x = 0;
}
else if(x > 2 * Math.PI){
x = 2 * Math.PI;
}
return x;
}
//************************* Rank ********************************************
public void Rank(double[][] values, double[] fitness){
int i = 0;
int j = 0;
int length = fitness.length;
for(i = 1; i < length; i++){
for(j = 0; j< i; j++){
if(this.Dominance(values[i], values[j]) == 1){
fitness[j] ++;
}
else if(this.Dominance(values[i], values[j]) == -1){
fitness[i] ++;
}
else if(this.Dominance(values[i], values[j]) == 0){
//Do nothing
}
}
}
}
//************************* Main *********************************************
public static void main(String args[]){
//
MOEA myMOEA = new MOEA();
final int count = 100; // population is 100 per generation
final int gen = 50; // altogether 100 generations
double[] pops = new double[count];
double[] child = new double[count];
double[][] values = new double[count][2];
double[][] chv = new double[count][2]; //child values
double[] fitness = new double[count];
double[] chf = new double[count]; //child fitness
int i = 0;
int gencount = 1;
for(; i < count; i++){
pops[i] = 2 * Math.PI * Math.random();
}
while(gencount <= gen){ // ending criteria
for(i = 0; i < count; i++){
myMOEA.Compute(pops[i], values[i]);
} // Computation completed
for(i = 0; i < count; i++){
child[i] = myMOEA.Mutate(pops[i]);
}
for(i = 0; i < count; i++){
myMOEA.Compute(child[i], chv[i]);
}
for(i = 0; i < count; i++){
myMOEA.Rank(values, fitness);
myMOEA.Rank(chv, chf); // compute all the ranks
}
for(i = 0; i < count; i++){
if(fitness[i] < chf[i]){
//do nothing, pops[i] remains the same element
}
else if(fitness[i] >= chf[i]){
pops[i] = child[i]; // copy the child[i] to pops[i]
fitness[i] = chf[i];
}
}
gencount ++;
}
for(i = 0; i < count; i++){
if(fitness[i] == 0){
System.out.println("the " + i + " th element is non-dominated, and " +
"the value is " + pops[i]/Math.PI + " PI ");
}
}
}
}