Skip to content

Instantly share code, notes, and snippets.

@sgraaf
Created October 21, 2018 21:27
Show Gist options
  • Save sgraaf/f82821d12f55f63a1e74b10d2946f19c to your computer and use it in GitHub Desktop.
Save sgraaf/f82821d12f55f63a1e74b10d2946f19c to your computer and use it in GitHub Desktop.
import java.util.Comparator;
import java.util.Random;
import java.util.Properties;
import java.util.Arrays;
public class FitnessComparator implements Comparator<double[]>{
@Override
public int compare(double[] entry1, double[] entry2) {
double field1 = entry1[20];
double field2 = entry2[20];
if (field1>field2) {
return 1;
} else if (field1==field2) {
return 0;
} else {
return -1;
}
}
}
import org.vu.contest.ContestSubmission;
import org.vu.contest.ContestEvaluation;
import java.util.Comparator;
import java.util.Random;
import java.util.Properties;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
public class player8 implements ContestSubmission {
static final int ind_size = 10 + 10 + 1; //index 10-19 = sigmas, index 20 = fitness
static final double dev = 1/(Math.sqrt(20));
static final double dev2 = 1/(Math.sqrt(2.0 * Math.sqrt(10)));
static final double eps0 = 0.001;
Random rnd_;
ContestEvaluation evaluation_;
private int evaluations_limit_;
public player8() {
rnd_ = new Random();
}
public void setSeed(long seed) {
// Set seed of algortihms random process
rnd_.setSeed(seed);
}
public void setEvaluation(ContestEvaluation evaluation) {
// Set evaluation problem used in the run
evaluation_ = evaluation;
// Get evaluation properties
Properties props = evaluation.getProperties();
// Get evaluation limit
evaluations_limit_ = Integer.parseInt(props.getProperty("Evaluations"));
// Property keys depend on specific evaluation
// E.g. double param = Double.parseDouble(props.getProperty("property_name"));
boolean isMultimodal = Boolean.parseBoolean(props.getProperty("Multimodal"));
boolean hasStructure = Boolean.parseBoolean(props.getProperty("Regular"));
boolean isSeparable = Boolean.parseBoolean(props.getProperty("Separable"));
// Do sth with property values, e.g. specify relevant settings of your algorithm
if(isMultimodal){
// Do sth
} else {
// Do sth else
}
}
// Discrete recombination method
public double[][] discrete_recombination(double[] parent_1, double[] parent_2) {
double[][] children = new double[2][ind_size];
// Genes + Sigmas
for (int j = 0; j < 20; j++) {
if (rnd_.nextDouble() <= 0.5) {
children[0][j] = parent_1[j];
children[1][j] = parent_2[j];
} else {
children[0][j] = parent_1[j];
children[1][j] = parent_2[j];
}
}
return children;
}
// Simple arithmic recombination method
public double[][] simple_arithmic_recombination(double[] parent_1, double[] parent_2, int k, double alpha) {
double[][] children = new double[2][ind_size];
// Genes
for (int j = 0; j < k; j++) {
children[0][j] = parent_1[j];
children[1][j] = parent_2[j];
}
for (int j = k; j < 10; j++) {
children[0][j] = alpha * parent_1[j] + (1 - alpha) * parent_2[j];
children[1][j] = alpha * parent_2[j] + (1 - alpha) * parent_1[j];
}
// Sigmas
for (int j = 10; j < k + 10; j++) {
children[0][j] = parent_1[j];
children[1][j] = parent_2[j];
}
for (int j = k + 10; j < 20; j++) {
children[0][j] = alpha * parent_1[j] + (1 - alpha) * parent_2[j];
children[1][j] = alpha * parent_2[j] + (1 - alpha) * parent_1[j];
}
return children;
}
// Single arithmic recombination method
public double[][] single_arithmic_recombination(double[] parent_1, double[] parent_2, double alpha) {
double[][] children = new double[2][ind_size];
int k = rnd_.nextInt(10);
children[0] = parent_1;
children[1] = parent_2;
// Genes
children[0][k] = alpha * parent_1[k] + (1 - alpha) * parent_2[k];
children[1][k] = alpha * parent_2[k] + (1 - alpha) * parent_1[k];
// Sigmas
children[0][k + 10] = alpha * parent_1[k + 10] + (1 - alpha) * parent_2[k + 10];
children[1][k + 10] = alpha * parent_2[k + 10] + (1 - alpha) * parent_1[k + 10];
return children;
}
// Whole arithmic recombination method
public double[][] whole_arithmic_recombination(double[] parent_1, double[] parent_2, double alpha) {
double[][] children = new double[2][ind_size];
// Genes + Sigmas
for (int j = 0; j < 20; j++) {
children[0][j] = alpha * parent_1[j] + (1 - alpha) * parent_2[j];
children[1][j] = alpha * parent_2[j] + (1 - alpha) * parent_1[j];
}
return children;
}
// Blend crossover method
public double[][] blend_crossover(double[] parent_1, double[] parent_2, double gamma) {
double[][] children = new double[2][ind_size];
// Genes
for (int j = 0; j < 10; j++) {
//Squeeze the values between [-5.0, 5.0] with the max-min
children[0][j] = Math.max(-5.0, Math.min((1 - gamma) * parent_1[j] + gamma * parent_2[j], 5.0));
children[1][j] = Math.max(-5.0, Math.min((1 - gamma) * parent_2[j] + gamma * parent_1[j], 5.0));
}
// Sigmas
for (int j = 10; j < 20; j++) {
children[0][j] = Math.max(eps0, (1 - gamma) * parent_1[j] + gamma * parent_2[j]);
children[1][j] = Math.max(eps0, (1 - gamma) * parent_2[j] + gamma * parent_1[j]);
}
return children;
}
// Mutation method
public double[] mutation(double[] individual) {
//double[] mutated = new double[ind_size];
double oldFitness = individual[20];
double N01 = rnd_.nextGaussian();
double sigma;
double mut;
double oldSigma;
double newFitness;
double N2;
for (int j = 0; j < 10; j++) {
oldSigma = individual[10 + j];
N2 = rnd_.nextGaussian();
sigma = Math.max(eps0, oldSigma * (Math.exp(dev * N2 + dev2 * N01)));
individual[10 + j] = sigma;
mut = sigma * N2;
individual[j] = Math.max(-5.0, Math.min(individual[j] + mut, 5.0));
}
// newFitness = (double) evaluation_.evaluate(Arrays.copyOfRange(individual, 0, 10));
// individual[20] = newFitness;
// System.out.println("Change in fitness: " + oldFitness + " --> " + newFitness);
return individual;
}
public void run() {
int pop_size = 50; // mu
int children_size = 7 * pop_size; // lambda = 7 * pop_size is a good setting fur (mu, lambda)-selection
int crossover_type = Integer.parseInt(System.getProperty("crossover_type", "5")); // 1: discrete recombination, 2: simple arithmic recombination, 3: single arithmic recombination, 4: whole arithmic recombination, 5: blend crossover
// Run your algorithm here
// Set the seed to our system time
rnd_.setSeed(System.currentTimeMillis());
// Initializaiton
int evals = 0;
double[][] population = new double[pop_size][ind_size];
// Parameters
// Mutation
double sigma = 0.1;
// Crossover
// Arithmetic recombination
int k = 7;
double alpha_1 = 0.5;
// Blend crossover
double alpha_2 = 0.5; // The book reports that the creators of BLX found 0.5 to be the best value for alpha
// Create the population by filling the empty array of arrays of doubles
for (int i = 0; i < pop_size; i++) {
for (int j = 0; j < 10; j++) {
population[i][j] = 10 * rnd_.nextDouble() - 5; //Adapted this to get real values in the range of [-5,5]
population[i][10 + j] = sigma;
}
//System.out.println(Arrays.toString(population[i]));
}
// Evaluation of initial population
// System.out.println();
// System.out.println("1. Evaluation of population");
for (int i = 0; i < pop_size; i++) {
population[i][20] = (double) evaluation_.evaluate(Arrays.copyOfRange(population[i],0,10));
}
while (evals < evaluations_limit_) {
// Parent selection
// System.out.println();
// System.out.println("2. Parent selection");
// Initialize the children array
int children_count = 0;
double[][] children = new double[children_size][ind_size];
// Uniform selection of parents
while (children_count < children_size) {
int selected_parents_count = 0;
double[][] selected_parents = new double[2][ind_size]; // 2 parents are needed for children creation
while (selected_parents_count < 2) {
// Pick a member of the population with uniform probability to become a parent
int selected_parent = rnd_.nextInt(pop_size);
// Select this parent and update the counter
selected_parents[selected_parents_count] = population[selected_parent];
selected_parents_count++;
}
// Apply crossover operators and create children
// System.out.println("4. Recombination (using " + crossover_types[crossover_type] + ")");
double[][] tmp_children = new double[2][ind_size];
// Use the selected crossover operator
switch (crossover_type) {
case 1: tmp_children = discrete_recombination(selected_parents[0], selected_parents[1]);
break;
case 2: tmp_children = simple_arithmic_recombination(selected_parents[0], selected_parents[1], k, alpha_1);
break;
case 3: tmp_children = single_arithmic_recombination(selected_parents[0], selected_parents[1], alpha_1);
break;
case 4: tmp_children = whole_arithmic_recombination(selected_parents[0], selected_parents[1], alpha_1);
break;
case 5: double u = rnd_.nextDouble();
double gamma = (1 - 2 * alpha_2) * u - alpha_2;
tmp_children = blend_crossover(selected_parents[0], selected_parents[1], gamma);
break;
}
// Apply mutation operators
// System.out.println();
// System.out.println("3. Mutation");
// Mutate the selected parents
children[children_count] = mutation(tmp_children[0]);
children[children_count + 1] = mutation(tmp_children[1]);
// Evaluate of children
// System.out.println("5. Evaluation of children");
children[children_count][20] = (double) evaluation_.evaluate(Arrays.copyOfRange(children[children_count], 0, 10));
children[children_count + 1][20] = (double) evaluation_.evaluate(Arrays.copyOfRange(children[children_count + 1], 0, 10));
// Increment our children counter
children_count += 2;
}
// Select survivors using (mu, lambda)-selection
// Sort the current children on their fitness
java.util.Arrays.sort(children, new FitnessComparator());
// Set the new population to the best 5 parents + mu - 5 children
for (int i = 0; i < pop_size; i++) {
population[i] = children[children.length - (1 + i)];
}
// System.out.println("Iteration: " + evals);
evals++;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment