// Path: src/main/java/com/amihaiemil/eva/concurrency/AsynchronousEvaThread.java
// public final class AsynchronousEvaThread implements Runnable {
//     private SolutionCallback callback;
//     private Eva algorithm;
//     private String threadName;
//     private int runs;
//     private Thread tr;
//     /**
//      * Constructor.
//      * @param algorithm The evolutionary algorithm to be run.
//      * @param callback The callback logic (what to do with the found solution?).
//      * @param name The name of this runnable (it will be suffixed with _nrOfRuns).
//      */
//     public AsynchronousEvaThread(Eva algorithm, SolutionCallback callback, String name) {
//         this.algorithm = algorithm;
//         this.callback = callback;
//         this.threadName = name;
//     }
// 
//     public void run() {
//         callback.execute(algorithm.calculate());
//     }
// 
//     /**
//      * Start the execution of a new thread.
//      */
//     public void start() {
//         runs++;
//         tr = new Thread(this, threadName + "_" + runs);
//         tr.start();
// 
//     }
// 
//     public void stop() {
//         tr.interrupt();
//     }
// }
// 
// Path: src/main/java/com/amihaiemil/eva/concurrency/SolutionCallback.java
// public interface SolutionCallback {
//     /**
//      * Logic to be performed on the found solution.
//      * @param result The algorithm's final solution.
//      */
//     void execute(Solution result);
// }
// 
// Path: src/main/java/com/amihaiemil/eva/util/BinaryArraySolutionsGenerator.java
// public class BinaryArraySolutionsGenerator implements SolutionsGenerator {
//     /**
//      * Size of the representation array.
//      */
//     private int size;
//     private Random r = new Random();
//     public BinaryArraySolutionsGenerator(int size) {
//         this.size = size;
//     }
//     public Solution generateRandomSolution() {
//         NumericalRepresentation representation = new NumericalRepresentation();
//         for(int i=0;i<size;i++) {
//             representation = representation.addNumber(r.nextInt(2));
//         }
//         Solution generated = new BinaryArraySolution(new Random());
//         generated.setRepresentation(representation);
//         return generated;
//     }
// }


import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.amihaiemil.eva.concurrency.AsynchronousEvaThread;
import com.amihaiemil.eva.concurrency.SolutionCallback;
import org.junit.Test;
import com.amihaiemil.eva.backpack.FitnessForBackpackEvaluator;
import com.amihaiemil.eva.util.BinaryArraySolutionsGenerator;
import static org.junit.Assert.assertTrue;
import java.util.Random;
     * @throws Exception If something goes wrong.
     */
    @Test
    public void asyncSimpleEvaFindsASolution() throws InterruptedException, ExecutionException {
        // The algorithm should stop  when the found solution is acceptable.
        final Condition solutionIsAcceptable = new Condition() {
            public boolean passed(Solution solution) {
                return solution.isAcceptable();
            }
        };
        SolutionCallback assertsCallback = new SolutionCallback() {
            public void execute(Solution result) {
                assertTrue(result != null);
                assertTrue(solutionIsAcceptable.passed(result));
            }
        };
        Eva eva = initAlgorithm(solutionIsAcceptable);
        AsynchronousEvaThread asyncEva = new AsynchronousEvaThread(eva, assertsCallback, "testAsyncEva");

        final ExecutorService executorService = Executors.newSingleThreadExecutor();
        Future future = executorService.submit(asyncEva);
        assertTrue(future.get()==null);
    }

    private Eva initAlgorithm(Condition solutionIsAcceptable) {
        long[] weights = new long[10];
        for(int i=0;i<10;i++) {
            weights[i] = r.nextInt(100);
        }
        FitnessForBackpackEvaluator evaluator = new FitnessForBackpackEvaluator(weights);
// Path: src/main/java/com/amihaiemil/eva/concurrency/AsynchronousEvaThread.java
// public final class AsynchronousEvaThread implements Runnable {
//     private SolutionCallback callback;
//     private Eva algorithm;
//     private String threadName;
//     private int runs;
//     private Thread tr;
//     /**
//      * Constructor.
//      * @param algorithm The evolutionary algorithm to be run.
//      * @param callback The callback logic (what to do with the found solution?).
//      * @param name The name of this runnable (it will be suffixed with _nrOfRuns).
//      */
//     public AsynchronousEvaThread(Eva algorithm, SolutionCallback callback, String name) {
//         this.algorithm = algorithm;
//         this.callback = callback;
//         this.threadName = name;
//     }
// 
//     public void run() {
//         callback.execute(algorithm.calculate());
//     }
// 
//     /**
//      * Start the execution of a new thread.
//      */
//     public void start() {
//         runs++;
//         tr = new Thread(this, threadName + "_" + runs);
//         tr.start();
// 
//     }
// 
//     public void stop() {
//         tr.interrupt();
//     }
// }
// 
// Path: src/main/java/com/amihaiemil/eva/concurrency/SolutionCallback.java
// public interface SolutionCallback {
//     /**
//      * Logic to be performed on the found solution.
//      * @param result The algorithm's final solution.
//      */
//     void execute(Solution result);
// }
// 
// Path: src/main/java/com/amihaiemil/eva/util/BinaryArraySolutionsGenerator.java
// public class BinaryArraySolutionsGenerator implements SolutionsGenerator {
//     /**
//      * Size of the representation array.
//      */
//     private int size;
//     private Random r = new Random();
//     public BinaryArraySolutionsGenerator(int size) {
//         this.size = size;
//     }
//     public Solution generateRandomSolution() {
//         NumericalRepresentation representation = new NumericalRepresentation();
//         for(int i=0;i<size;i++) {
//             representation = representation.addNumber(r.nextInt(2));
//         }
//         Solution generated = new BinaryArraySolution(new Random());
//         generated.setRepresentation(representation);
//         return generated;
//     }
// }


// Path: src/test/java/com/amihaiemil/eva/EvolutionaryAlgorithmTest.java
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.amihaiemil.eva.concurrency.AsynchronousEvaThread;
import com.amihaiemil.eva.concurrency.SolutionCallback;
import org.junit.Test;
import com.amihaiemil.eva.backpack.FitnessForBackpackEvaluator;
import com.amihaiemil.eva.util.BinaryArraySolutionsGenerator;
import static org.junit.Assert.assertTrue;
import java.util.Random;

     * @throws Exception If something goes wrong.
     */
    @Test
    public void asyncSimpleEvaFindsASolution() throws InterruptedException, ExecutionException {
        // The algorithm should stop  when the found solution is acceptable.
        final Condition solutionIsAcceptable = new Condition() {
            public boolean passed(Solution solution) {
                return solution.isAcceptable();
            }
        };
        SolutionCallback assertsCallback = new SolutionCallback() {
            public void execute(Solution result) {
                assertTrue(result != null);
                assertTrue(solutionIsAcceptable.passed(result));
            }
        };
        Eva eva = initAlgorithm(solutionIsAcceptable);
        AsynchronousEvaThread asyncEva = new AsynchronousEvaThread(eva, assertsCallback, "testAsyncEva");

        final ExecutorService executorService = Executors.newSingleThreadExecutor();
        Future future = executorService.submit(asyncEva);
        assertTrue(future.get()==null);
    }

    private Eva initAlgorithm(Condition solutionIsAcceptable) {
        long[] weights = new long[10];
        for(int i=0;i<10;i++) {
            weights[i] = r.nextInt(100);
        }
        FitnessForBackpackEvaluator evaluator = new FitnessForBackpackEvaluator(weights);
        BinaryArraySolutionsGenerator generator = new BinaryArraySolutionsGenerator(weights.length);