Skip to content

Instantly share code, notes, and snippets.

@dhadka
Last active September 21, 2015 19:02
Show Gist options
  • Save dhadka/559be932acc55b1ada6b to your computer and use it in GitHub Desktop.
Save dhadka/559be932acc55b1ada6b to your computer and use it in GitHub Desktop.
Temporary fix to a bug in the island model example, where TimSort throws an exception indicating the comparator's contract is violated
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Semaphore;
import org.apache.commons.math3.random.MersenneTwister;
import org.apache.commons.math3.random.RandomAdaptor;
import org.apache.commons.math3.random.SynchronizedRandomGenerator;
import org.moeaframework.algorithm.NSGAII;
import org.moeaframework.algorithm.PeriodicAction;
import org.moeaframework.algorithm.PeriodicAction.FrequencyType;
import org.moeaframework.core.NondominatedPopulation;
import org.moeaframework.core.NondominatedSortingPopulation;
import org.moeaframework.core.PRNG;
import org.moeaframework.core.Population;
import org.moeaframework.core.Problem;
import org.moeaframework.core.Solution;
import org.moeaframework.core.comparator.ChainedComparator;
import org.moeaframework.core.comparator.CrowdingComparator;
import org.moeaframework.core.comparator.ParetoDominanceComparator;
import org.moeaframework.core.operator.RandomInitialization;
import org.moeaframework.core.operator.TournamentSelection;
import org.moeaframework.core.spi.OperatorFactory;
import org.moeaframework.core.spi.ProblemFactory;
public class IslandModel {
public static void main(String[] args) {
final int numberOfIslands = 4;
final int maxEvaluations = 1000000;
final int migrationFrequency = 10000;
final Problem problem = ProblemFactory.getInstance().getProblem("DTLZ2_2");
final Map<Thread, NSGAII> islands = new HashMap<Thread, NSGAII>();
// this semaphore is used to synchronize locking to prevent deadlocks
final Semaphore semaphore = new Semaphore(1);
// need to use a synchronized random number generator instead of the
// default
PRNG.setRandom(new RandomAdaptor(
new SynchronizedRandomGenerator(
new MersenneTwister())));
for (int i = 0; i < numberOfIslands; i++) {
// create an instance of NSGAII for each island
final NSGAII nsgaii = new NSGAII(
problem,
new SynchronizedPopulation(),
null,
new TournamentSelection(2,
new ChainedComparator(
new ParetoDominanceComparator(),
new CrowdingComparator())),
OperatorFactory.getInstance().getVariation(
null,
new Properties(),
problem),
new RandomInitialization(problem, 100));
// create a periodic action for handling migration events
final PeriodicAction migration = new PeriodicAction(nsgaii,
migrationFrequency,
FrequencyType.EVALUATIONS) {
@Override
public void doAction() {
try {
Thread thisThread = Thread.currentThread();
for (Thread otherThread : islands.keySet()) {
if (otherThread != thisThread) {
semaphore.acquire();
NondominatedSortingPopulation oldIsland =
(NondominatedSortingPopulation)islands.get(thisThread).getPopulation();
NondominatedSortingPopulation newIsland =
(NondominatedSortingPopulation)islands.get(otherThread).getPopulation();
synchronized (oldIsland) {
synchronized (newIsland) {
int emigrant = PRNG.nextInt(oldIsland.size());
newIsland.add(oldIsland.get(emigrant).copy());
newIsland.truncate(newIsland.size()-1);
System.out.println("Sent solution " +
emigrant + " from " +
Thread.currentThread().getName() +
" to " + otherThread.getName());
}
}
semaphore.release();
}
}
} catch (InterruptedException e) {
// ignore
}
}
};
// create the thread for running each island concurrently
Thread thread = new Thread() {
public void run() {
while (migration.getNumberOfEvaluations() < maxEvaluations) {
migration.step();
}
}
};
islands.put(thread, nsgaii);
}
// start the threads
for (Thread thread : islands.keySet()) {
thread.start();
}
// wait for the threads to finish and aggregate the result
NondominatedPopulation result = new NondominatedPopulation();
for (Thread thread : islands.keySet()) {
try {
thread.join();
result.addAll(islands.get(thread).getResult());
} catch (InterruptedException e) {
System.out.println("Thread " + thread.getId() + " was interrupted!");
}
}
System.out.println(result.size());
}
// synchronized version of the NondominatedSortingPopulation
public static class SynchronizedPopulation extends NondominatedSortingPopulation {
@Override
public boolean add(Solution solution) {
synchronized (this) {
return super.add(solution);
}
}
@Override
public void replace(int index, Solution solution) {
synchronized (this) {
super.replace(index, solution);
}
}
@Override
public Solution get(int index) {
synchronized (this) {
return super.get(index);
}
}
@Override
public void remove(int index) {
synchronized (this) {
super.remove(index);
}
}
@Override
public boolean remove(Solution solution) {
synchronized (this) {
return super.remove(solution);
}
}
@Override
public void clear() {
synchronized (this) {
super.clear();
}
}
@Override
public Iterator<Solution> iterator() {
synchronized (this) {
return super.iterator();
}
}
@Override
public void sort(Comparator<? super Solution> comparator) {
synchronized (this) {
super.sort(comparator);
}
}
@Override
public void truncate(int size, Comparator<? super Solution> comparator) {
synchronized (this) {
super.truncate(size, comparator);
}
}
@Override
public void truncate(int size) {
synchronized (this) {
super.truncate(size);
}
}
@Override
public void prune(int size) {
synchronized (this) {
super.prune(size);
}
}
@Override
public void update() {
synchronized (this) {
super.update();
}
}
@Override
public int indexOf(Solution solution) {
synchronized (this) {
return super.indexOf(solution);
}
}
@Override
public boolean addAll(Iterable<? extends Solution> iterable) {
synchronized (this) {
return super.addAll(iterable);
}
}
@Override
public <T extends Solution> boolean addAll(T[] solutions) {
synchronized (this) {
return super.addAll(solutions);
}
}
@Override
public boolean contains(Solution solution) {
synchronized (this) {
return super.contains(solution);
}
}
@Override
public boolean containsAll(Iterable<? extends Solution> iterable) {
synchronized (this) {
return super.containsAll(iterable);
}
}
@Override
public <T extends Solution> boolean containsAll(T[] solutions) {
synchronized (this) {
return super.containsAll(solutions);
}
}
@Override
public boolean isEmpty() {
synchronized (this) {
return super.isEmpty();
}
}
@Override
public boolean removeAll(Iterable<? extends Solution> iterable) {
synchronized (this) {
return super.removeAll(iterable);
}
}
@Override
public <T extends Solution> boolean removeAll(T[] solutions) {
synchronized (this) {
return super.removeAll(solutions);
}
}
@Override
public int size() {
synchronized (this) {
return super.size();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment